From 35d2de298f42bb43b0f5cbbbbfa63f0e16492a67 Mon Sep 17 00:00:00 2001 From: pmla Date: Fri, 15 Feb 2019 18:49:23 -0500 Subject: [PATCH 1/9] added license information to all files updated documentation added example file added graphene structure --- doc/src/compute_ptm_atom.txt | 12 +- examples/USER/ptm/ptm_example.in | 47 + src/USER-PTM/compute_ptm_atom.cpp | 115 +- src/USER-PTM/ptm_alloy_types.cpp | 22 +- src/USER-PTM/ptm_alloy_types.h | 9 + src/USER-PTM/ptm_alt_templates.h | 127 ++ src/USER-PTM/ptm_canonical_coloured.cpp | 11 +- src/USER-PTM/ptm_canonical_coloured.h | 9 + src/USER-PTM/ptm_constants.h | 276 ++-- src/USER-PTM/ptm_convex_hull_incremental.cpp | 11 +- src/USER-PTM/ptm_convex_hull_incremental.h | 9 + src/USER-PTM/ptm_deformation_gradient.cpp | 9 + src/USER-PTM/ptm_deformation_gradient.h | 355 ++++-- src/USER-PTM/ptm_functions.h | 16 +- src/USER-PTM/ptm_fundamental_mappings.h | 452 ++++--- src/USER-PTM/ptm_graph_data.cpp | 1207 +++++++++--------- src/USER-PTM/ptm_graph_data.h | 9 + src/USER-PTM/ptm_graph_tools.cpp | 11 +- src/USER-PTM/ptm_graph_tools.h | 9 + src/USER-PTM/ptm_index.cpp | 362 ++++-- src/USER-PTM/ptm_initialize_data.cpp | 11 +- src/USER-PTM/ptm_initialize_data.h | 186 ++- src/USER-PTM/ptm_neighbour_ordering.cpp | 322 ++++- src/USER-PTM/ptm_neighbour_ordering.h | 20 +- src/USER-PTM/ptm_normalize_vertices.cpp | 9 + src/USER-PTM/ptm_normalize_vertices.h | 9 + src/USER-PTM/ptm_polar.cpp | 17 +- src/USER-PTM/ptm_polar.h | 10 +- src/USER-PTM/ptm_quat.cpp | 412 +++--- src/USER-PTM/ptm_quat.h | 22 +- src/USER-PTM/ptm_structure_matcher.cpp | 80 +- src/USER-PTM/ptm_structure_matcher.h | 10 + src/USER-PTM/ptm_voronoi_cell.cpp | 108 ++ src/USER-PTM/ptm_voronoi_cell.h | 43 + src/USER-PTM/ptm_voronoi_config.h | 43 + 35 files changed, 2856 insertions(+), 1524 deletions(-) create mode 100644 examples/USER/ptm/ptm_example.in create mode 100644 src/USER-PTM/ptm_alt_templates.h diff --git a/doc/src/compute_ptm_atom.txt b/doc/src/compute_ptm_atom.txt index 57e143404e..86aea9aeba 100644 --- a/doc/src/compute_ptm_atom.txt +++ b/doc/src/compute_ptm_atom.txt @@ -38,20 +38,20 @@ ico (icosahedral) = 4 sc (simple cubic) = 5 dcub (diamond cubic) = 6 dhex (diamond hexagonal) = 7 -other = 8 :ul +graphene = 8 :ul -The value of the PTM structure will be 0 for atoms not in the specified +The value of the PTM structure will be 0 for unknown types and -1 for atoms not in the specified compute group. The choice of structures to search for can be specified using the "structures" argument, which is a hyphen-separated list of structure keywords. Two convenient pre-set options are provided: default: fcc-hcp-bcc-ico -all: fcc-hcp-bcc-ico-sc-dcub-dhex :ul +all: fcc-hcp-bcc-ico-sc-dcub-dhex-graphene :ul The 'default' setting detects the same structures as the Common Neighbor Analysis method. -The 'all' setting searches for all structure types. A small performance penalty is -incurred for the diamond structures, so it is not recommended to use this option if -it is known that the simulation does not contain diamond structures. +The 'all' setting searches for all structure types. A performance penalty is +incurred for the diamond and graphene structures, so it is not recommended to use this option if +it is known that the simulation does not contain these structures. PTM identifies structures using two steps. First, a graph isomorphism test is used diff --git a/examples/USER/ptm/ptm_example.in b/examples/USER/ptm/ptm_example.in new file mode 100644 index 0000000000..07e4f2acaa --- /dev/null +++ b/examples/USER/ptm/ptm_example.in @@ -0,0 +1,47 @@ +# LAMMPS Input File for Grain Boundaries +# Mark Tschopp, Dec2009 +# Modified by PM Larsen to demonstrate the use of PTM in LAMMPS +# This file will generate a single Sigma5(310) STGB and run PTM + +# ---------- Initialize Simulation --------------------- +clear +units metal +dimension 3 +boundary p p p +atom_style atomic + +# ---------- Create Sigma5(310) Structure --------- +lattice fcc 4.05 +region whole block 0.000000 12.807225 -64.0361225 64.0361225 0.000000 4.050000 units box +create_box 2 whole +region upper block INF INF 0.000000 64.0361225 INF INF units box +lattice fcc 4.05 orient x 0 3 1 orient y 0 -1 3 orient z 1 0 0 +create_atoms 1 region upper +region lower block INF INF -64.0361225 0.000000 INF INF units box +lattice fcc 4.05 orient x 0 3 -1 orient y 0 1 3 orient z 1 0 0 +create_atoms 2 region lower +group upper type 1 +group lower type 2 + +mass 1 1.0 +mass 2 1.0 + +# ---------- Define Interatomic Potential --------------------- +pair_style lj/cut 2.5 +pair_coeff * * 1 1 +pair_coeff 1 1 1 1.1 2.8 + +# ---------- Displace atoms and delete overlapping atoms --------------------- +displace_atoms upper move 0 0 0 units lattice +delete_atoms overlap 0.35 lower upper + +# ---------- Define PTM settings (default structures, RMSD threshold of 0.1) ------------------- +compute ptm all ptm/atom default 0.1 + +# ---------- Dump data into Data file ------------- +reset_timestep 0 +dump 1 all cfg 10000 dump.ptm_example_*.cfg mass type xs ys zs c_ptm[1] c_ptm[2] c_ptm[3] c_ptm[4] c_ptm[5] c_ptm[6] c_ptm[7] +dump_modify 1 element Al Al +run 1 + +print "All done" diff --git a/src/USER-PTM/compute_ptm_atom.cpp b/src/USER-PTM/compute_ptm_atom.cpp index eb0138de26..cdfd933936 100644 --- a/src/USER-PTM/compute_ptm_atom.cpp +++ b/src/USER-PTM/compute_ptm_atom.cpp @@ -36,10 +36,9 @@ under #include "ptm_functions.h" -#define MAX_NEIGHBORS 30 #define NUM_COLUMNS 7 -#define UNKNOWN 0 -#define OTHER 8 +#define PTM_LAMMPS_UNKNOWN -1 +#define PTM_LAMMPS_OTHER 0 using namespace LAMMPS_NS; @@ -69,7 +68,9 @@ ComputePTMAtom::ComputePTMAtom(LAMMPS *lmp, int narg, char **arg) char *ptr = structures; const char *strings[] = {"fcc", "hcp", "bcc", "ico", "sc", - "dcub", "dhex", "all", "default"}; + "dcub", "dhex", "graphene", "all", "default"}; + int num_strings = sizeof(strings) / sizeof(const char*); + int32_t flags[] = { PTM_CHECK_FCC, PTM_CHECK_HCP, @@ -78,6 +79,7 @@ ComputePTMAtom::ComputePTMAtom(LAMMPS *lmp, int narg, char **arg) PTM_CHECK_SC, PTM_CHECK_DCUB, PTM_CHECK_DHEX, + PTM_CHECK_GRAPHENE, PTM_CHECK_ALL, PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_BCC | PTM_CHECK_ICO}; @@ -85,7 +87,7 @@ ComputePTMAtom::ComputePTMAtom(LAMMPS *lmp, int narg, char **arg) while (*ptr != '\0') { bool found = false; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < num_strings; i++) { int len = strlen(strings[i]); if (strncmp(ptr, strings[i], len) == 0) { input_flags |= flags[i]; @@ -156,47 +158,83 @@ void ComputePTMAtom::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ +typedef struct +{ + double **x; + int *numneigh; + int **firstneigh; + int *ilist; + int nlocal; + +} ptmnbrdata_t; + + typedef struct { int index; double d; } ptmnbr_t; + static bool sorthelper_compare(ptmnbr_t const &a, ptmnbr_t const &b) { return a.d < b.d; } -static int get_neighbors(double *pos, int jnum, int *jlist, double **x, - double (*nbr)[3]) { +static int get_neighbours(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, double (*nbr_pos)[3]) +{ + ptmnbrdata_t* data = (ptmnbrdata_t*)vdata; + + double **x = data->x; + double *pos = x[atom_index]; + + int *jlist = NULL; + int jnum = 0; + if (atom_index < data->nlocal) { + jlist = data->firstneigh[atom_index]; + jnum = data->numneigh[atom_index]; + } + else { + jlist = data->firstneigh[central_index]; + jnum = data->numneigh[central_index]; + } ptmnbr_t *nbr_order = new ptmnbr_t[jnum]; + int count = 0; for (int jj = 0; jj < jnum; jj++) { int j = jlist[jj]; j &= NEIGHMASK; + if (j == atom_index) + continue; double dx = pos[0] - x[j][0]; double dy = pos[1] - x[j][1]; double dz = pos[2] - x[j][2]; double rsq = dx * dx + dy * dy + dz * dz; - nbr_order[jj].index = j; - nbr_order[jj].d = rsq; + nbr_order[count].index = j; + nbr_order[count].d = rsq; + count++; } - std::sort(nbr_order, nbr_order + jnum, &sorthelper_compare); - int num_nbrs = std::min(MAX_NEIGHBORS, jnum); + std::sort(nbr_order, nbr_order + count, &sorthelper_compare); + int num_nbrs = std::min(num - 1, count); - nbr[0][0] = nbr[0][1] = nbr[0][2] = 0; + nbr_pos[0][0] = nbr_pos[0][1] = nbr_pos[0][2] = 0; + nbr_indices[0] = atom_index; + numbers[0] = 0; for (int jj = 0; jj < num_nbrs; jj++) { int j = nbr_order[jj].index; - nbr[jj + 1][0] = x[j][0] - pos[0]; - nbr[jj + 1][1] = x[j][1] - pos[1]; - nbr[jj + 1][2] = x[j][2] - pos[2]; + nbr_pos[jj + 1][0] = x[j][0] - pos[0]; + nbr_pos[jj + 1][1] = x[j][1] - pos[1]; + nbr_pos[jj + 1][2] = x[j][2] - pos[2]; + + nbr_indices[jj + 1] = j; + numbers[jj + 1] = 0; } delete[] nbr_order; - return num_nbrs; + return num_nbrs + 1; } void ComputePTMAtom::compute_peratom() { @@ -229,50 +267,29 @@ void ComputePTMAtom::compute_peratom() { double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; + ptmnbrdata_t nbrlist = {x, numneigh, firstneigh, ilist, atom->nlocal}; for (int ii = 0; ii < inum; ii++) { int i = ilist[ii]; - output[i][0] = UNKNOWN; + output[i][0] = PTM_LAMMPS_UNKNOWN; if (!(mask[i] & groupbit)) continue; - double *pos = x[i]; - - int *jlist = firstneigh[i]; int jnum = numneigh[i]; if (jnum <= 0) continue; - // get neighbours ordered by increasing distance - double nbr[MAX_NEIGHBORS + 1][3]; - int num_nbrs = get_neighbors(pos, jnum, jlist, x, nbr); - - // check that we have enough neighbours for the desired structure types - int32_t flags = 0; - if (num_nbrs >= PTM_NUM_NBRS_SC && (input_flags & PTM_CHECK_SC)) - flags |= PTM_CHECK_SC; - if (num_nbrs >= PTM_NUM_NBRS_FCC && (input_flags & PTM_CHECK_FCC)) - flags |= PTM_CHECK_FCC; - if (num_nbrs >= PTM_NUM_NBRS_HCP && (input_flags & PTM_CHECK_HCP)) - flags |= PTM_CHECK_HCP; - if (num_nbrs >= PTM_NUM_NBRS_ICO && (input_flags & PTM_CHECK_ICO)) - flags |= PTM_CHECK_ICO; - if (num_nbrs >= PTM_NUM_NBRS_BCC && (input_flags & PTM_CHECK_BCC)) - flags |= PTM_CHECK_BCC; - if (num_nbrs >= PTM_NUM_NBRS_DCUB && (input_flags & PTM_CHECK_DCUB)) - flags |= PTM_CHECK_DCUB; - if (num_nbrs >= PTM_NUM_NBRS_DHEX && (input_flags & PTM_CHECK_DHEX)) - flags |= PTM_CHECK_DHEX; // now run PTM - int8_t mapping[MAX_NEIGHBORS + 1]; int32_t type, alloy_type; - double scale, rmsd, interatomic_distance, lattice_constant; - double q[4], F[9], F_res[3], U[9], P[9]; - ptm_index(local_handle, flags, num_nbrs + 1, nbr, NULL, true, &type, - &alloy_type, &scale, &rmsd, q, F, F_res, U, P, mapping, - &interatomic_distance, &lattice_constant); + double scale, rmsd, interatomic_distance; + double q[4]; + bool standard_orientations = false; + ptm_index(local_handle, i, get_neighbours, (void*)&nbrlist, + input_flags, standard_orientations, + &type, &alloy_type, &scale, &rmsd, q, + NULL, NULL, NULL, NULL, &interatomic_distance, NULL, NULL); if (rmsd > rmsd_threshold) { type = PTM_MATCH_NONE; @@ -280,8 +297,10 @@ void ComputePTMAtom::compute_peratom() { // printf("%d type=%d rmsd=%f\n", i, type, rmsd); - if (type == PTM_MATCH_NONE) - type = OTHER; + if (type == PTM_MATCH_NONE) { + type = PTM_LAMMPS_OTHER; + rmsd = INFINITY; + } output[i][0] = type; output[i][1] = rmsd; diff --git a/src/USER-PTM/ptm_alloy_types.cpp b/src/USER-PTM/ptm_alloy_types.cpp index 151de3e5b8..40e8211386 100644 --- a/src/USER-PTM/ptm_alloy_types.cpp +++ b/src/USER-PTM/ptm_alloy_types.cpp @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include #include "ptm_constants.h" #include "ptm_initialize_data.h" @@ -6,8 +15,8 @@ namespace ptm { #define NUM_ALLOY_TYPES 3 static uint32_t typedata[NUM_ALLOY_TYPES][3] = { - {PTM_MATCH_FCC, PTM_ALLOY_L10, 0x000001fe}, - {PTM_MATCH_FCC, PTM_ALLOY_L12_CU, 0x0000001e}, + {PTM_MATCH_FCC, PTM_ALLOY_L10, 0x00000db6}, + {PTM_MATCH_FCC, PTM_ALLOY_L12_CU, 0x00000492}, {PTM_MATCH_FCC, PTM_ALLOY_L12_AU, 0x00001ffe}, }; @@ -78,6 +87,10 @@ static int32_t canonical_alloy_representation(const refdata_t* ref, int8_t* mapp int32_t find_alloy_type(const refdata_t* ref, int8_t* mapping, int32_t* numbers) { + for (int i=0;inum_nbrs+1;i++) + if (numbers[i] == -1) + return PTM_ALLOY_NONE; + if (test_pure(ref->num_nbrs, numbers)) return PTM_ALLOY_PURE; @@ -97,6 +110,11 @@ int32_t find_alloy_type(const refdata_t* ref, int8_t* mapping, int32_t* numbers) if (test_shell_structure(ref, mapping, numbers, 4)) return PTM_ALLOY_SIC; + + if (ref->type == PTM_MATCH_GRAPHENE) + if (test_shell_structure(ref, mapping, numbers, 3)) + return PTM_ALLOY_BN; + return PTM_ALLOY_NONE; } diff --git a/src/USER-PTM/ptm_alloy_types.h b/src/USER-PTM/ptm_alloy_types.h index 559e0a7490..e51ec1dd01 100644 --- a/src/USER-PTM/ptm_alloy_types.h +++ b/src/USER-PTM/ptm_alloy_types.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_ALLOY_TYPES_H #define PTM_ALLOY_TYPES_H diff --git a/src/USER-PTM/ptm_alt_templates.h b/src/USER-PTM/ptm_alt_templates.h new file mode 100644 index 0000000000..7a6524e70e --- /dev/null +++ b/src/USER-PTM/ptm_alt_templates.h @@ -0,0 +1,127 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PTM_ALT_TEMPLATES_H +#define PTM_ALT_TEMPLATES_H + +#include + + +const double ptm_template_hcp_alt1[PTM_NUM_POINTS_HCP][3] = { + { 0, 0, 0 }, + { 1, 0, 0 }, + { -0.5, -sqrt(3)/2, 0 }, + { -0.5, -sqrt(3)/6, -sqrt(6)/3 }, + { 0, sqrt(3)/3, -sqrt(6)/3 }, + { 0.5, -sqrt(3)/6, -sqrt(6)/3 }, + { -1, 0, 0 }, + { -0.5, sqrt(3)/2, 0 }, + { 0.5, sqrt(3)/2, 0 }, + { 0.5, -sqrt(3)/2, 0 }, + { 0.5, -sqrt(3)/6, sqrt(6)/3 }, + { 0, sqrt(3)/3, sqrt(6)/3 }, + { -0.5, -sqrt(3)/6, sqrt(6)/3 }, +}; + +const double ptm_template_dcub_alt1[PTM_NUM_POINTS_DCUB][3] = { + { 0, 0, 0 }, + { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, +}; + +const double ptm_template_dhex_alt1[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, +}; + +const double ptm_template_dhex_alt2[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, +}; + +const double ptm_template_dhex_alt3[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, +}; + + +const double ptm_template_graphene_alt1[PTM_NUM_POINTS_GRAPHENE][3] = { + { 0, 0, 0 }, + { 3*sqrt(3)/22-9./11, -3./22+3*sqrt(3)/11, 0 }, + { 9./11-3*sqrt(3)/22, -3./22+3*sqrt(3)/11, 0 }, + { 0, -6*sqrt(3)/11+3./11, 0 }, + { -18./11+3*sqrt(3)/11, 0, 0 }, + { 3*sqrt(3)/22-9./11, -9./22+9*sqrt(3)/11, 0 }, + { 9./11-3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/11+18./11, 0, 0 }, + { 9./11-3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, + { 3*sqrt(3)/22-9./11, -9*sqrt(3)/11+9./22, 0 }, +}; + +#endif + diff --git a/src/USER-PTM/ptm_canonical_coloured.cpp b/src/USER-PTM/ptm_canonical_coloured.cpp index 56fcd3a603..660c618711 100644 --- a/src/USER-PTM/ptm_canonical_coloured.cpp +++ b/src/USER-PTM/ptm_canonical_coloured.cpp @@ -1,4 +1,13 @@ -#include +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include #include #include #include "ptm_graph_tools.h" diff --git a/src/USER-PTM/ptm_canonical_coloured.h b/src/USER-PTM/ptm_canonical_coloured.h index f8e2a7af5d..3ba2daebcd 100644 --- a/src/USER-PTM/ptm_canonical_coloured.h +++ b/src/USER-PTM/ptm_canonical_coloured.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_CANONICAL_COLOURED_H #define PTM_CANONICAL_COLOURED_H diff --git a/src/USER-PTM/ptm_constants.h b/src/USER-PTM/ptm_constants.h index f868f51e84..f607a9132d 100644 --- a/src/USER-PTM/ptm_constants.h +++ b/src/USER-PTM/ptm_constants.h @@ -1,30 +1,43 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_CONSTANTS_H #define PTM_CONSTANTS_H +#include + //------------------------------------ // definitions //------------------------------------ #define PTM_NO_ERROR 0 -#define PTM_CHECK_FCC (1 << 0) -#define PTM_CHECK_HCP (1 << 1) -#define PTM_CHECK_BCC (1 << 2) -#define PTM_CHECK_ICO (1 << 3) -#define PTM_CHECK_SC (1 << 4) -#define PTM_CHECK_DCUB (1 << 5) -#define PTM_CHECK_DHEX (1 << 6) -#define PTM_CHECK_NONDIAMOND (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC) -#define PTM_CHECK_ALL (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC | PTM_CHECK_DCUB | PTM_CHECK_DHEX) +#define PTM_CHECK_FCC (1 << 0) +#define PTM_CHECK_HCP (1 << 1) +#define PTM_CHECK_BCC (1 << 2) +#define PTM_CHECK_ICO (1 << 3) +#define PTM_CHECK_SC (1 << 4) +#define PTM_CHECK_DCUB (1 << 5) +#define PTM_CHECK_DHEX (1 << 6) +#define PTM_CHECK_GRAPHENE (1 << 7) +#define PTM_CHECK_DEFAULT (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC) +#define PTM_CHECK_ALL (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC | PTM_CHECK_DCUB | PTM_CHECK_DHEX | PTM_CHECK_GRAPHENE) -#define PTM_MATCH_NONE 0 -#define PTM_MATCH_FCC 1 -#define PTM_MATCH_HCP 2 -#define PTM_MATCH_BCC 3 -#define PTM_MATCH_ICO 4 -#define PTM_MATCH_SC 5 -#define PTM_MATCH_DCUB 6 -#define PTM_MATCH_DHEX 7 +#define PTM_MATCH_NONE 0 +#define PTM_MATCH_FCC 1 +#define PTM_MATCH_HCP 2 +#define PTM_MATCH_BCC 3 +#define PTM_MATCH_ICO 4 +#define PTM_MATCH_SC 5 +#define PTM_MATCH_DCUB 6 +#define PTM_MATCH_DHEX 7 +#define PTM_MATCH_GRAPHENE 8 #define PTM_ALLOY_NONE 0 #define PTM_ALLOY_PURE 1 @@ -33,9 +46,10 @@ #define PTM_ALLOY_L12_AU 4 #define PTM_ALLOY_B2 5 #define PTM_ALLOY_SIC 6 +#define PTM_ALLOY_BN 7 -#define PTM_MAX_INPUT_POINTS 35 +#define PTM_MAX_INPUT_POINTS 19 #define PTM_MAX_NBRS 16 #define PTM_MAX_POINTS (PTM_MAX_NBRS + 1) #define PTM_MAX_FACETS 28 //2 * PTM_MAX_NBRS - 4 @@ -52,16 +66,18 @@ #define PTM_NUM_NBRS_SC 6 #define PTM_NUM_NBRS_DCUB 16 #define PTM_NUM_NBRS_DHEX 16 +#define PTM_NUM_NBRS_GRAPHENE 9 #define PTM_NUM_POINTS_FCC (PTM_NUM_NBRS_FCC + 1) #define PTM_NUM_POINTS_HCP (PTM_NUM_NBRS_HCP + 1) #define PTM_NUM_POINTS_BCC (PTM_NUM_NBRS_BCC + 1) #define PTM_NUM_POINTS_ICO (PTM_NUM_NBRS_ICO + 1) #define PTM_NUM_POINTS_SC (PTM_NUM_NBRS_SC + 1) -#define PTM_NUM_POINTS_DCUB (PTM_NUM_NBRS_DCUB + 1) -#define PTM_NUM_POINTS_DHEX (PTM_NUM_NBRS_DHEX + 1) +#define PTM_NUM_POINTS_DCUB (PTM_NUM_NBRS_DCUB + 1) +#define PTM_NUM_POINTS_DHEX (PTM_NUM_NBRS_DHEX + 1) +#define PTM_NUM_POINTS_GRAPHENE (PTM_NUM_NBRS_GRAPHENE + 1) -const int ptm_num_nbrs[8] = {0, PTM_NUM_NBRS_FCC, PTM_NUM_NBRS_HCP, PTM_NUM_NBRS_BCC, PTM_NUM_NBRS_ICO, PTM_NUM_NBRS_SC, PTM_NUM_NBRS_DCUB, PTM_NUM_NBRS_DHEX}; +const int ptm_num_nbrs[9] = {0, PTM_NUM_NBRS_FCC, PTM_NUM_NBRS_HCP, PTM_NUM_NBRS_BCC, PTM_NUM_NBRS_ICO, PTM_NUM_NBRS_SC, PTM_NUM_NBRS_DCUB, PTM_NUM_NBRS_DHEX, PTM_NUM_NBRS_GRAPHENE}; //------------------------------------ // template structures @@ -69,106 +85,134 @@ const int ptm_num_nbrs[8] = {0, PTM_NUM_NBRS_FCC, PTM_NUM_NBRS_HCP, PTM_NUM_NBRS //these point sets have barycentre {0, 0, 0} and are scaled such that the mean neighbour distance is 1 -const double ptm_template_fcc[PTM_NUM_POINTS_FCC][3] = { { 0. , 0. , 0. }, - { 0. , 0.707106781187, 0.707106781187 }, - { 0. , -0.707106781187, -0.707106781187 }, - { 0. , 0.707106781187, -0.707106781187 }, - { 0. , -0.707106781187, 0.707106781187 }, - { 0.707106781187, 0. , 0.707106781187 }, - { -0.707106781187, 0. , -0.707106781187 }, - { 0.707106781187, 0. , -0.707106781187 }, - { -0.707106781187, 0. , 0.707106781187 }, - { 0.707106781187, 0.707106781187, 0. }, - { -0.707106781187, -0.707106781187, 0. }, - { 0.707106781187, -0.707106781187, 0. }, - { -0.707106781187, 0.707106781187, 0. } }; +const double ptm_template_fcc[PTM_NUM_POINTS_FCC][3] = { + { 0, 0, 0 }, + { sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, sqrt(2)/2 }, + { sqrt(2)/2, 0, sqrt(2)/2 }, + { -sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, -sqrt(2)/2, -sqrt(2)/2 }, + { -sqrt(2)/2, 0, -sqrt(2)/2 }, + { -sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, -sqrt(2)/2, sqrt(2)/2 }, + { -sqrt(2)/2, 0, sqrt(2)/2 }, + { sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, -sqrt(2)/2 }, + { sqrt(2)/2, 0, -sqrt(2)/2 }, +}; -const double ptm_template_hcp[PTM_NUM_POINTS_HCP][3] = { { 0. , 0. , 0. }, - { 0.707106781186, 0. , 0.707106781186 }, - { -0.235702260395, -0.942809041583, -0.235702260395 }, - { 0.707106781186, 0.707106781186, 0. }, - { -0.235702260395, -0.235702260395, -0.942809041583 }, - { 0. , 0.707106781186, 0.707106781186 }, - { -0.942809041583, -0.235702260395, -0.235702260395 }, - { -0.707106781186, 0.707106781186, 0. }, - { 0. , 0.707106781186, -0.707106781186 }, - { 0.707106781186, 0. , -0.707106781186 }, - { 0.707106781186, -0.707106781186, 0. }, - { -0.707106781186, 0. , 0.707106781186 }, - { 0. , -0.707106781186, 0.707106781186 } }; +const double ptm_template_hcp[PTM_NUM_POINTS_HCP][3] = { + { 0, 0, 0 }, + { 0.5, -sqrt(3)/2, 0 }, + { -1, 0, 0 }, + { -0.5, sqrt(3)/6, -sqrt(6)/3 }, + { 0.5, sqrt(3)/6, -sqrt(6)/3 }, + { 0, -sqrt(3)/3, -sqrt(6)/3 }, + { -0.5, sqrt(3)/2, 0 }, + { 0.5, sqrt(3)/2, 0 }, + { 1, 0, 0 }, + { -0.5, -sqrt(3)/2, 0 }, + { 0, -sqrt(3)/3, sqrt(6)/3 }, + { 0.5, sqrt(3)/6, sqrt(6)/3 }, + { -0.5, sqrt(3)/6, sqrt(6)/3 }, +}; -const double ptm_template_bcc[PTM_NUM_POINTS_BCC][3] = { { 0. , 0. , 0. }, - { -0.541451884327, -0.541451884327, -0.541451884327 }, - { 0.541451884327, 0.541451884327, 0.541451884327 }, - { 0.541451884327, -0.541451884327, -0.541451884327 }, - { -0.541451884327, 0.541451884327, 0.541451884327 }, - { -0.541451884327, 0.541451884327, -0.541451884327 }, - { 0.541451884327, -0.541451884327, 0.541451884327 }, - { -0.541451884327, -0.541451884327, 0.541451884327 }, - { 0.541451884327, 0.541451884327, -0.541451884327 }, - { 0. , 0. , -1.082903768655 }, - { 0. , 0. , 1.082903768655 }, - { 0. , -1.082903768655, 0. }, - { 0. , 1.082903768655, 0. }, - { -1.082903768655, 0. , 0. }, - { 1.082903768655, 0. , 0. } }; +const double ptm_template_bcc[PTM_NUM_POINTS_BCC][3] = { + { 0, 0, 0 }, + { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, + { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, + { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, + { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, + { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, + { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, + { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, + { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, + { 14*sqrt(3)/3-7, 0, 0 }, + { 7-14*sqrt(3)/3, 0, 0 }, + { 0, 14*sqrt(3)/3-7, 0 }, + { 0, 7-14*sqrt(3)/3, 0 }, + { 0, 0, 14*sqrt(3)/3-7 }, + { 0, 0, 7-14*sqrt(3)/3 }, +}; -const double ptm_template_ico[PTM_NUM_POINTS_ICO][3] = { { 0. , 0. , 0. }, - { 0. , 0.525731112119, 0.850650808352 }, - { 0. , -0.525731112119, -0.850650808352 }, - { 0. , 0.525731112119, -0.850650808352 }, - { 0. , -0.525731112119, 0.850650808352 }, - { -0.525731112119, -0.850650808352, 0. }, - { 0.525731112119, 0.850650808352, 0. }, - { 0.525731112119, -0.850650808352, 0. }, - { -0.525731112119, 0.850650808352, 0. }, - { -0.850650808352, 0. , -0.525731112119 }, - { 0.850650808352, 0. , 0.525731112119 }, - { 0.850650808352, 0. , -0.525731112119 }, - { -0.850650808352, 0. , 0.525731112119 } }; +const double ptm_template_ico[PTM_NUM_POINTS_ICO][3] = { + { 0, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + { -sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, + { sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, + { 0, -2*sqrt(5)/5, -sqrt(5)/5 }, + { 0, 2*sqrt(5)/5, sqrt(5)/5 }, + { sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, + { -sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, + { -sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, + { sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, + { sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, + { -sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, +}; -const double ptm_template_sc[PTM_NUM_POINTS_SC][3] = { { 0. , 0. , 0. }, - { 0. , 0. , -1. }, - { 0. , 0. , 1. }, - { 0. , -1. , 0. }, - { 0. , 1. , 0. }, - { -1. , 0. , 0. }, - { 1. , 0. , 0. } }; +const double ptm_template_sc[PTM_NUM_POINTS_SC][3] = { + { 0, 0, 0 }, + { 0, 0, -1 }, + { 0, 0, 1 }, + { 0, -1, 0 }, + { 0, 1, 0 }, + { -1, 0, 0 }, + { 1, 0, 0 }, +}; -const double ptm_template_dcub[PTM_NUM_POINTS_DCUB][3] = { { 0. , 0. , 0. }, - { -0.391491627053, 0.391491627053, 0.391491627053 }, - { -0.391491627053, -0.391491627053, -0.391491627053 }, - { 0.391491627053, -0.391491627053, 0.391491627053 }, - { 0.391491627053, 0.391491627053, -0.391491627053 }, - { -0.782983254107, 0. , 0.782983254107 }, - { -0.782983254107, 0.782983254107, 0. }, - { 0. , 0.782983254107, 0.782983254107 }, - { -0.782983254107, -0.782983254107, 0. }, - { -0.782983254107, 0. , -0.782983254107 }, - { 0. , -0.782983254107, -0.782983254107 }, - { 0. , -0.782983254107, 0.782983254107 }, - { 0.782983254107, -0.782983254107, 0. }, - { 0.782983254107, 0. , 0.782983254107 }, - { 0. , 0.782983254107, -0.782983254107 }, - { 0.782983254107, 0. , -0.782983254107 }, - { 0.782983254107, 0.782983254107, 0. } }; +const double ptm_template_dcub[PTM_NUM_POINTS_DCUB][3] = { + { 0, 0, 0 }, + { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, +}; + +const double ptm_template_dhex[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, +}; + +const double ptm_template_graphene[PTM_NUM_POINTS_GRAPHENE][3] = { + { 0, 0, 0 }, + { 0, -3./11+6*sqrt(3)/11, 0 }, + { -3*sqrt(3)/22+9./11, -3*sqrt(3)/11+3./22, 0 }, + { -9./11+3*sqrt(3)/22, -3*sqrt(3)/11+3./22, 0 }, + { -9./11+3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/22+9./11, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/11+18./11, 0, 0 }, + { -3*sqrt(3)/22+9./11, -9*sqrt(3)/11+9./22, 0 }, + { -9./11+3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, + { -18./11+3*sqrt(3)/11, 0, 0 }, +}; -const double ptm_template_dhex[PTM_NUM_POINTS_DHEX][3] = { { 0. , 0. , 0. }, - { -0.391491627053, -0.391491627053, -0.391491627053 }, - { 0.391491627053, -0.391491627053, 0.391491627053 }, - { -0.391491627053, 0.391491627053, 0.391491627053 }, - { 0.391491627053, 0.391491627053, -0.391491627053 }, - { -0.260994418036, -1.043977672142, -0.260994418036 }, - { -1.043977672142, -0.260994418036, -0.260994418036 }, - { -0.260994418036, -0.260994418036, -1.043977672142 }, - { 0.782983254107, 0. , 0.782983254107 }, - { 0.782983254107, -0.782983254107, 0. }, - { 0. , -0.782983254107, 0.782983254107 }, - { 0. , 0.782983254107, 0.782983254107 }, - { -0.782983254107, 0.782983254107, 0. }, - { -0.782983254107, 0. , 0.782983254107 }, - { 0.782983254107, 0.782983254107, 0. }, - { 0. , 0.782983254107, -0.782983254107 }, - { 0.782983254107, 0. , -0.782983254107 } }; #endif diff --git a/src/USER-PTM/ptm_convex_hull_incremental.cpp b/src/USER-PTM/ptm_convex_hull_incremental.cpp index 2b5972261b..e7f93eea06 100644 --- a/src/USER-PTM/ptm_convex_hull_incremental.cpp +++ b/src/USER-PTM/ptm_convex_hull_incremental.cpp @@ -1,6 +1,15 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include #include -#include +#include #include #include #include "ptm_convex_hull_incremental.h" diff --git a/src/USER-PTM/ptm_convex_hull_incremental.h b/src/USER-PTM/ptm_convex_hull_incremental.h index 6474723907..da4a810676 100644 --- a/src/USER-PTM/ptm_convex_hull_incremental.h +++ b/src/USER-PTM/ptm_convex_hull_incremental.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_CONVEX_HULL_INCREMENTAL_H #define PTM_CONVEX_HULL_INCREMENTAL_H diff --git a/src/USER-PTM/ptm_deformation_gradient.cpp b/src/USER-PTM/ptm_deformation_gradient.cpp index fc851920a6..afa592f2c4 100644 --- a/src/USER-PTM/ptm_deformation_gradient.cpp +++ b/src/USER-PTM/ptm_deformation_gradient.cpp @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include "ptm_deformation_gradient.h" namespace ptm { diff --git a/src/USER-PTM/ptm_deformation_gradient.h b/src/USER-PTM/ptm_deformation_gradient.h index 32836da44d..2a6f8693ea 100644 --- a/src/USER-PTM/ptm_deformation_gradient.h +++ b/src/USER-PTM/ptm_deformation_gradient.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_DEFORMATION_GRADIENT_H #define PTM_DEFORMATION_GRADIENT_H @@ -8,139 +17,247 @@ namespace ptm { void calculate_deformation_gradient(int num_points, const double (*ideal_points)[3], int8_t* mapping, double (*normalized)[3], const double (*penrose)[3], double* F, double* res); -//sc -#define k_sc 0.5 -const double penrose_sc[PTM_NUM_POINTS_SC][3] = { - {0, 0, 0}, - {0, 0, -k_sc}, - {0, 0, k_sc}, - {0, -k_sc, 0}, - {0, k_sc, 0}, - {-k_sc, 0, 0}, - {k_sc, 0, 0}, - }; +const double penrose_sc[PTM_NUM_POINTS_SC][3] = { + { 0, 0, 0 }, + { 0, 0, -0.5 }, + { 0, 0, 0.5 }, + { 0, -0.5, 0 }, + { 0, 0.5, 0 }, + { -0.5, 0, 0 }, + { 0.5, 0, 0 }, +}; -//fcc -#define k_fcc 0.17677669529663678216 const double penrose_fcc[PTM_NUM_POINTS_FCC][3] = { - {0, 0, 0}, - {0, k_fcc, k_fcc}, - {0, -k_fcc, -k_fcc}, - {0, k_fcc, -k_fcc}, - {0, -k_fcc, k_fcc}, - {k_fcc, 0, k_fcc}, - {-k_fcc, 0, -k_fcc}, - {k_fcc, 0, -k_fcc}, - {-k_fcc, 0, k_fcc}, - {k_fcc, k_fcc, -0}, - {-k_fcc, -k_fcc, 0}, - {k_fcc, -k_fcc, 0}, - {-k_fcc, k_fcc, -0}, - }; + { 0, 0, 0 }, + { sqrt(2)/8, sqrt(2)/8, 0 }, + { 0, sqrt(2)/8, sqrt(2)/8 }, + { sqrt(2)/8, 0, sqrt(2)/8 }, + { -sqrt(2)/8, -sqrt(2)/8, 0 }, + { 0, -sqrt(2)/8, -sqrt(2)/8 }, + { -sqrt(2)/8, 0, -sqrt(2)/8 }, + { -sqrt(2)/8, sqrt(2)/8, 0 }, + { 0, -sqrt(2)/8, sqrt(2)/8 }, + { -sqrt(2)/8, 0, sqrt(2)/8 }, + { sqrt(2)/8, -sqrt(2)/8, 0 }, + { 0, sqrt(2)/8, -sqrt(2)/8 }, + { sqrt(2)/8, 0, -sqrt(2)/8 }, +}; -//hcp -#define k_hcp 0.17677669529663678216 const double penrose_hcp[PTM_NUM_POINTS_HCP][3] = { - {0, 0, 0}, - {k_hcp, 0, k_hcp}, - {-k_hcp/3, -4*k_hcp/3, -k_hcp/3}, - {k_hcp, k_hcp, 0}, - {-k_hcp/3, -k_hcp/3, -4*k_hcp/3}, - {0, k_hcp, k_hcp}, - {-4*k_hcp/3, -k_hcp/3, -k_hcp/3}, - {-k_hcp, k_hcp, -0}, - {0, k_hcp, -k_hcp}, - {k_hcp, 0, -k_hcp}, - {k_hcp, -k_hcp, 0}, - {-k_hcp, 0, k_hcp}, - {0, -k_hcp, k_hcp}, - }; + { 0, 0, 0 }, + { 1./8, -sqrt(3)/8, 0 }, + { -1./4, 0, 0 }, + { -1./8, sqrt(3)/24, -sqrt(6)/12 }, + { 1./8, sqrt(3)/24, -sqrt(6)/12 }, + { 0, -sqrt(3)/12, -sqrt(6)/12 }, + { -1./8, sqrt(3)/8, 0 }, + { 1./8, sqrt(3)/8, 0 }, + { 1./4, 0, 0 }, + { -1./8, -sqrt(3)/8, 0 }, + { 0, -sqrt(3)/12, sqrt(6)/12 }, + { 1./8, sqrt(3)/24, sqrt(6)/12 }, + { -1./8, sqrt(3)/24, sqrt(6)/12 }, +}; + +const double penrose_hcp_alt1[PTM_NUM_POINTS_HCP][3] = { + { 0, 0, 0 }, + { 1./4, 0, 0 }, + { -1./8, -sqrt(3)/8, 0 }, + { -1./8, -sqrt(3)/24, -sqrt(6)/12 }, + { 0, sqrt(3)/12, -sqrt(6)/12 }, + { 1./8, -sqrt(3)/24, -sqrt(6)/12 }, + { -1./4, 0, 0 }, + { -1./8, sqrt(3)/8, 0 }, + { 1./8, sqrt(3)/8, 0 }, + { 1./8, -sqrt(3)/8, 0 }, + { 1./8, -sqrt(3)/24, sqrt(6)/12 }, + { 0, sqrt(3)/12, sqrt(6)/12 }, + { -1./8, -sqrt(3)/24, sqrt(6)/12 }, +}; -//ico -#define k_ico 0.13143277802974323576 -#define phi 1.61803398874989490253 -//((1.0 + sqrt(5)) / 2) const double penrose_ico[PTM_NUM_POINTS_ICO][3] = { - {0, 0, 0}, - {0, k_ico, phi*k_ico}, - {0, -k_ico, -phi*k_ico}, - {0, k_ico, -phi*k_ico}, - {0, -k_ico, phi*k_ico}, - {-k_ico, -phi*k_ico, -0}, - {k_ico, phi*k_ico, 0}, - {k_ico, -phi*k_ico, 0}, - {-k_ico, phi*k_ico, -0}, - {-phi*k_ico, 0, -k_ico}, - {phi*k_ico, 0, k_ico}, - {phi*k_ico, 0, -k_ico}, - {-phi*k_ico, 0, k_ico}, - }; + { 0, 0, 0 }, + { 0, 0, 0.25 }, + { 0, 0, -0.25 }, + { -sqrt(-10*sqrt(5) + 50)/40, sqrt(5)/40 + 1./8, -sqrt(5)/20 }, + { sqrt(-10*sqrt(5) + 50)/40, -1./8 - sqrt(5)/40, sqrt(5)/20 }, + { 0, -sqrt(5)/10, -sqrt(5)/20 }, + { 0, sqrt(5)/10, sqrt(5)/20 }, + { sqrt(10*sqrt(5) + 50)/40, -1./8 + sqrt(5)/40, -sqrt(5)/20 }, + { -sqrt(10*sqrt(5) + 50)/40, -sqrt(5)/40 + 1./8, sqrt(5)/20 }, + { -sqrt(10*sqrt(5) + 50)/40, -1./8 + sqrt(5)/40, -sqrt(5)/20 }, + { sqrt(10*sqrt(5) + 50)/40, -sqrt(5)/40 + 1./8, sqrt(5)/20 }, + { sqrt(-10*sqrt(5) + 50)/40, sqrt(5)/40 + 1./8, -sqrt(5)/20 }, + { -sqrt(-10*sqrt(5) + 50)/40, -1./8 - sqrt(5)/40, sqrt(5)/20 }, +}; -//bcc -#define k_bcc 0.11543038598460284017 const double penrose_bcc[PTM_NUM_POINTS_BCC][3] = { - {0, 0, 0}, - {-k_bcc, -k_bcc, -k_bcc}, - {k_bcc, k_bcc, k_bcc}, - {k_bcc, -k_bcc, -k_bcc}, - {-k_bcc, k_bcc, k_bcc}, - {-k_bcc, k_bcc, -k_bcc}, - {k_bcc, -k_bcc, k_bcc}, - {-k_bcc, -k_bcc, k_bcc}, - {k_bcc, k_bcc, -k_bcc}, - {0, 0, -2*k_bcc}, - {0, 0, 2*k_bcc}, - {0, -2*k_bcc, 0}, - {0, 2*k_bcc, 0}, - {-2*k_bcc, 0, 0}, - {2*k_bcc, 0, -0}, - }; + { 0, 0, 0 }, + { 3./56 + sqrt(3)/28, 3./56 + sqrt(3)/28, 3./56 + sqrt(3)/28 }, + { -sqrt(3)/28 - 3./56, 3./56 + sqrt(3)/28, 3./56 + sqrt(3)/28 }, + { 3./56 + sqrt(3)/28, 3./56 + sqrt(3)/28, -sqrt(3)/28 - 3./56 }, + { -sqrt(3)/28 - 3./56, -sqrt(3)/28 - 3./56, 3./56 + sqrt(3)/28 }, + { 3./56 + sqrt(3)/28, -sqrt(3)/28 - 3./56, 3./56 + sqrt(3)/28 }, + { -sqrt(3)/28 - 3./56, 3./56 + sqrt(3)/28, -sqrt(3)/28 - 3./56 }, + { -sqrt(3)/28 - 3./56, -sqrt(3)/28 - 3./56, -sqrt(3)/28 - 3./56 }, + { 3./56 + sqrt(3)/28, -sqrt(3)/28 - 3./56, -sqrt(3)/28 - 3./56 }, + { 3./28 + sqrt(3)/14, 0, 0 }, + { -sqrt(3)/14 - 3./28, 0, 0 }, + { 0, 3./28 + sqrt(3)/14, 0 }, + { 0, -sqrt(3)/14 - 3./28, 0 }, + { 0, 0, 3./28 + sqrt(3)/14 }, + { 0, 0, -sqrt(3)/14 - 3./28 }, +}; -//dcub -#define kdcub 0.07095369570691034689 const double penrose_dcub[PTM_NUM_POINTS_DCUB][3] = { - { 0, 0, 0 }, - { -kdcub, kdcub, kdcub }, - { -kdcub, -kdcub, -kdcub }, - { kdcub, -kdcub, kdcub }, - { kdcub, kdcub, -kdcub }, - { -2 * kdcub, 0, 2 * kdcub }, - { -2 * kdcub, 2 * kdcub, 0 }, - { 0, 2 * kdcub, 2 * kdcub }, - { -2 * kdcub, -2 * kdcub, 0 }, - { -2 * kdcub, 0, -2 * kdcub }, - { 0, -2 * kdcub, -2 * kdcub }, - { 0, -2 * kdcub, 2 * kdcub }, - { 2 * kdcub, -2 * kdcub, 0 }, - { 2 * kdcub, 0, 2 * kdcub }, - { 0, 2 * kdcub, -2 * kdcub }, - { 2 * kdcub, 0, -2 * kdcub }, - { 2 * kdcub, 2 * kdcub, 0 }, - }; + { 0, 0, 0 }, + { 23./(48*(-sqrt(3) + 6*sqrt(2))), 23./(48*(-sqrt(3) + 6*sqrt(2))), 23./(48*(-sqrt(3) + 6*sqrt(2))) }, + { 23./(48*(-sqrt(3) + 6*sqrt(2))), -23./(-48*sqrt(3) + 288*sqrt(2)), -23./(-48*sqrt(3) + 288*sqrt(2)) }, + { -23./(-48*sqrt(3) + 288*sqrt(2)), -23./(-48*sqrt(3) + 288*sqrt(2)), 23./(48*(-sqrt(3) + 6*sqrt(2))) }, + { -23./(-48*sqrt(3) + 288*sqrt(2)), 23./(48*(-sqrt(3) + 6*sqrt(2))), -23./(-48*sqrt(3) + 288*sqrt(2)) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 23./(24*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 0, 23./(24*(-sqrt(3) + 6*sqrt(2))), 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 0, 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { 0, -23./(-24*sqrt(3) + 144*sqrt(2)), -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), -23./(-24*sqrt(3) + 144*sqrt(2)), 0 }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 0, -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), -23./(-24*sqrt(3) + 144*sqrt(2)), 0 }, + { 0, -23./(-24*sqrt(3) + 144*sqrt(2)), 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 0, 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 0, -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 23./(24*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 0, 23./(24*(-sqrt(3) + 6*sqrt(2))), -23./(-24*sqrt(3) + 144*sqrt(2)) }, +}; + +const double penrose_dcub_alt1[PTM_NUM_POINTS_DCUB][3] = { + { 0, 0, 0 }, + { 23./(48*(-sqrt(3) + 6*sqrt(2))), -23./(-48*sqrt(3) + 288*sqrt(2)), 23./(48*(-sqrt(3) + 6*sqrt(2))) }, + { 23./(48*(-sqrt(3) + 6*sqrt(2))), 23./(48*(-sqrt(3) + 6*sqrt(2))), -23./(-48*sqrt(3) + 288*sqrt(2)) }, + { -23./(-48*sqrt(3) + 288*sqrt(2)), -23./(-48*sqrt(3) + 288*sqrt(2)), -23./(-48*sqrt(3) + 288*sqrt(2)) }, + { -23./(-48*sqrt(3) + 288*sqrt(2)), 23./(48*(-sqrt(3) + 6*sqrt(2))), 23./(48*(-sqrt(3) + 6*sqrt(2))) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 0, 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { 0, -23./(-24*sqrt(3) + 144*sqrt(2)), 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), -23./(-24*sqrt(3) + 144*sqrt(2)), 0 }, + { 0, 23./(24*(-sqrt(3) + 6*sqrt(2))), -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 0, -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { 23./(24*(-sqrt(3) + 6*sqrt(2))), 23./(24*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 0, -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { 0, -23./(-24*sqrt(3) + 144*sqrt(2)), -23./(-24*sqrt(3) + 144*sqrt(2)) }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), -23./(-24*sqrt(3) + 144*sqrt(2)), 0 }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 23./(24*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23./(-24*sqrt(3) + 144*sqrt(2)), 0, 23./(24*(-sqrt(3) + 6*sqrt(2))) }, + { 0, 23./(24*(-sqrt(3) + 6*sqrt(2))), 23./(24*(-sqrt(3) + 6*sqrt(2))) }, +}; -#define kdhex 0.04730246380471011397 const double penrose_dhex[PTM_NUM_POINTS_DHEX][3] = { - { 0, 0, 0 }, - { -kdcub, -kdcub, -kdcub }, - { kdcub, -kdcub, kdcub }, - { -kdcub, kdcub, kdcub }, - { kdcub, kdcub, -kdcub }, - { -kdhex, -4 * kdhex, -kdhex }, - { -4 * kdhex, -kdhex, -kdhex }, - { -kdhex, -kdhex, -4 * kdhex }, - { 2 * kdcub, 0, 2 * kdcub }, - { 2 * kdcub, -2 * kdcub, 0 }, - { 0, -2 * kdcub, 2 * kdcub }, - { 0, 2 * kdcub, 2 * kdcub }, - { -2 * kdcub, 2 * kdcub, 0 }, - { -2 * kdcub, 0, 2 * kdcub }, - { 2 * kdcub, 2 * kdcub, 0 }, - { 0, 2 * kdcub, -2 * kdcub }, - { 2 * kdcub, 0, -2 * kdcub }, - }; + { 0, 0, 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 0, 0, 23*sqrt(3)/(48*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-24*sqrt(3) + 144*sqrt(2)), 0, 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 23*sqrt(2)/(24*(-sqrt(3) + 6*sqrt(2))), 0, 0 }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, +}; + +const double penrose_dhex_alt1[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-144*sqrt(3) + 864*sqrt(2)) }, + { 0, 0, 23*sqrt(3)/(48*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { -23*sqrt(2)/(-24*sqrt(3) + 144*sqrt(2)), 0, 0 }, + { 23*sqrt(2)/(24*(-sqrt(3) + 6*sqrt(2))), 0, 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, +}; + +const double penrose_dhex_alt2[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { 0, 0, -23*sqrt(3)/(-48*sqrt(3) + 288*sqrt(2)) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-24*sqrt(3) + 144*sqrt(2)), 0, 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(24*(-sqrt(3) + 6*sqrt(2))), 0, 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(144*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 0, -23*sqrt(6)/(-72*sqrt(3) + 432*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, +}; + +const double penrose_dhex_alt3[PTM_NUM_POINTS_DHEX][3] = { + { 0, 0, 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(144*(-sqrt(3) + 6*sqrt(2))) }, + { 0, 0, -23*sqrt(3)/(-48*sqrt(3) + 288*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(24*(-sqrt(3) + 6*sqrt(2))), 0, 0 }, + { -23*sqrt(2)/(-24*sqrt(3) + 144*sqrt(2)), 0, 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-48*sqrt(3) + 288*sqrt(2)), 0 }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(3)/(36*(-sqrt(3) + 6*sqrt(2))) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), 23*sqrt(6)/(48*(-sqrt(3) + 6*sqrt(2))), 0 }, + { -23*sqrt(2)/(-48*sqrt(3) + 288*sqrt(2)), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 0, 23*sqrt(6)/(72*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, + { 23*sqrt(2)/(48*(-sqrt(3) + 6*sqrt(2))), -23*sqrt(6)/(-144*sqrt(3) + 864*sqrt(2)), -23*sqrt(3)/(-36*sqrt(3) + 216*sqrt(2)) }, +}; + + +const double penrose_graphene[PTM_NUM_POINTS_GRAPHENE][3] = { + { 0, 0, 0 }, + { 0, 2./63 + 4*sqrt(3)/63, 0 }, + { sqrt(3)/63 + 2./21, -2*sqrt(3)/63 - 1./63, 0 }, + { -2./21 - sqrt(3)/63, -2*sqrt(3)/63 - 1./63, 0 }, + { -2./21 - sqrt(3)/63, 1./21 + 2*sqrt(3)/21, 0 }, + { sqrt(3)/63 + 2./21, 1./21 + 2*sqrt(3)/21, 0 }, + { 2*sqrt(3)/63 + 4./21, 0, 0 }, + { sqrt(3)/63 + 2./21, -2*sqrt(3)/21 - 1./21, 0 }, + { -2./21 - sqrt(3)/63, -2*sqrt(3)/21 - 1./21, 0 }, + { -4./21 - 2*sqrt(3)/63, 0, 0 }, +}; + +const double penrose_graphene_alt1[PTM_NUM_POINTS_GRAPHENE][3] = { + { 0, 0, 0 }, + { -2./21 - sqrt(3)/63, 1./63 + 2*sqrt(3)/63, 0 }, + { sqrt(3)/63 + 2./21, 1./63 + 2*sqrt(3)/63, 0 }, + { 0, -4*sqrt(3)/63 - 2./63, 0 }, + { -4./21 - 2*sqrt(3)/63, 0, 0 }, + { -2./21 - sqrt(3)/63, 1./21 + 2*sqrt(3)/21, 0 }, + { sqrt(3)/63 + 2./21, 1./21 + 2*sqrt(3)/21, 0 }, + { 2*sqrt(3)/63 + 4./21, 0, 0 }, + { sqrt(3)/63 + 2./21, -2*sqrt(3)/21 - 1./21, 0 }, + { -2./21 - sqrt(3)/63, -2*sqrt(3)/21 - 1./21, 0 }, +}; + } #endif - diff --git a/src/USER-PTM/ptm_functions.h b/src/USER-PTM/ptm_functions.h index cd67d4940d..75f444e510 100644 --- a/src/USER-PTM/ptm_functions.h +++ b/src/USER-PTM/ptm_functions.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_FUNCTIONS_H #define PTM_FUNCTIONS_H @@ -15,8 +24,11 @@ extern "C" { #endif -int ptm_index( ptm_local_handle_t local_handle, int32_t flags, int num_points, double (*atomic_positions)[3], int32_t* atomic_numbers, bool topological_ordering, //inputs - int32_t* p_type, int32_t* p_alloy_type, double* p_scale, double* p_rmsd, double* q, double* F, double* F_res, double* U, double* P, int8_t* mapping, double* p_interatomic_distance, double* p_lattice_constant); //outputs +int ptm_index( ptm_local_handle_t local_handle, + size_t atom_index, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, double (*nbr_pos)[3]), void* nbrlist, + int32_t flags, bool output_conventional_orientation, //inputs + int32_t* p_type, int32_t* p_alloy_type, double* p_scale, double* p_rmsd, double* q, double* F, double* F_res, double* U, double* P, double* p_interatomic_distance, double* p_lattice_constant, + size_t* output_indices); //outputs #ifdef __cplusplus diff --git a/src/USER-PTM/ptm_fundamental_mappings.h b/src/USER-PTM/ptm_fundamental_mappings.h index 35fae7f088..0276d5eca0 100644 --- a/src/USER-PTM/ptm_fundamental_mappings.h +++ b/src/USER-PTM/ptm_fundamental_mappings.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_FUNDAMENTAL_MAPPINGS_H #define PTM_FUNDAMENTAL_MAPPINGS_H @@ -11,172 +20,309 @@ namespace ptm { #define NUM_DCUB_MAPPINGS 12 #define NUM_DHEX_MAPPINGS 3 +#define NUM_GRAPHENE_MAPPINGS 6 +#define NUM_CONVENTIONAL_GRAPHENE_MAPPINGS 12 + +#define NUM_CONVENTIONAL_HEX_MAPPINGS 12 +#define NUM_CONVENTIONAL_DCUB_MAPPINGS 24 +#define NUM_CONVENTIONAL_DHEX_MAPPINGS 12 + + +//----------------------------------------------------------------------------- +// sc +//----------------------------------------------------------------------------- + const int8_t mapping_sc[NUM_CUBIC_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6}, - {0, 2, 1, 4, 3, 5, 6}, - {0, 2, 1, 3, 4, 6, 5}, - {0, 1, 2, 4, 3, 6, 5}, - {0, 3, 4, 5, 6, 1, 2}, - {0, 5, 6, 2, 1, 4, 3}, - {0, 6, 5, 1, 2, 4, 3}, - {0, 4, 3, 5, 6, 2, 1}, - {0, 5, 6, 1, 2, 3, 4}, - {0, 4, 3, 6, 5, 1, 2}, - {0, 3, 4, 6, 5, 2, 1}, - {0, 6, 5, 2, 1, 3, 4}, - {0, 3, 4, 2, 1, 5, 6}, - {0, 6, 5, 3, 4, 1, 2}, - {0, 1, 2, 5, 6, 4, 3}, - {0, 4, 3, 1, 2, 5, 6}, - {0, 5, 6, 3, 4, 2, 1}, - {0, 1, 2, 6, 5, 3, 4}, - {0, 2, 1, 5, 6, 3, 4}, - {0, 5, 6, 4, 3, 1, 2}, - {0, 3, 4, 1, 2, 6, 5}, - {0, 2, 1, 6, 5, 4, 3}, - {0, 6, 5, 4, 3, 2, 1}, - {0, 4, 3, 2, 1, 6, 5} }; + { 0, 1, 2, 3, 4, 5, 6}, + { 0, 3, 4, 2, 1, 5, 6}, + { 0, 6, 5, 3, 4, 1, 2}, + { 0, 1, 2, 5, 6, 4, 3}, + { 0, 1, 2, 6, 5, 3, 4}, + { 0, 5, 6, 3, 4, 2, 1}, + { 0, 4, 3, 1, 2, 5, 6}, + { 0, 3, 4, 5, 6, 1, 2}, + { 0, 6, 5, 2, 1, 3, 4}, + { 0, 5, 6, 2, 1, 4, 3}, + { 0, 3, 4, 6, 5, 2, 1}, + { 0, 6, 5, 1, 2, 4, 3}, + { 0, 4, 3, 6, 5, 1, 2}, + { 0, 4, 3, 5, 6, 2, 1}, + { 0, 5, 6, 1, 2, 3, 4}, + { 0, 2, 1, 4, 3, 5, 6}, + { 0, 2, 1, 5, 6, 3, 4}, + { 0, 5, 6, 4, 3, 1, 2}, + { 0, 6, 5, 4, 3, 2, 1}, + { 0, 2, 1, 6, 5, 4, 3}, + { 0, 2, 1, 3, 4, 6, 5}, + { 0, 3, 4, 1, 2, 6, 5}, + { 0, 4, 3, 2, 1, 6, 5}, + { 0, 1, 2, 4, 3, 6, 5}, +}; + +//----------------------------------------------------------------------------- +// fcc +//----------------------------------------------------------------------------- const int8_t mapping_fcc[NUM_CUBIC_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, - {0, 2, 1, 4, 3, 7, 8, 5, 6, 11, 12, 9, 10}, - {0, 3, 4, 1, 2, 6, 5, 8, 7, 12, 11, 10, 9}, - {0, 4, 3, 2, 1, 8, 7, 6, 5, 10, 9, 12, 11}, - {0, 9, 10, 11, 12, 1, 2, 4, 3, 5, 6, 8, 7}, - {0, 7, 8, 6, 5, 11, 12, 10, 9, 2, 1, 4, 3}, - {0, 8, 7, 5, 6, 10, 9, 11, 12, 4, 3, 2, 1}, - {0, 11, 12, 9, 10, 2, 1, 3, 4, 7, 8, 6, 5}, - {0, 5, 6, 8, 7, 9, 10, 12, 11, 1, 2, 3, 4}, - {0, 10, 9, 12, 11, 4, 3, 1, 2, 8, 7, 5, 6}, - {0, 12, 11, 10, 9, 3, 4, 2, 1, 6, 5, 7, 8}, - {0, 6, 5, 7, 8, 12, 11, 9, 10, 3, 4, 1, 2}, - {0, 3, 4, 2, 1, 9, 10, 11, 12, 7, 8, 5, 6}, - {0, 12, 11, 9, 10, 8, 7, 5, 6, 1, 2, 4, 3}, - {0, 5, 6, 7, 8, 4, 3, 2, 1, 11, 12, 10, 9}, - {0, 4, 3, 1, 2, 11, 12, 9, 10, 5, 6, 7, 8}, - {0, 9, 10, 12, 11, 7, 8, 6, 5, 3, 4, 2, 1}, - {0, 8, 7, 6, 5, 1, 2, 3, 4, 12, 11, 9, 10}, - {0, 7, 8, 5, 6, 3, 4, 1, 2, 9, 10, 12, 11}, - {0, 11, 12, 10, 9, 5, 6, 8, 7, 4, 3, 1, 2}, - {0, 1, 2, 4, 3, 12, 11, 10, 9, 8, 7, 6, 5}, - {0, 6, 5, 8, 7, 2, 1, 4, 3, 10, 9, 11, 12}, - {0, 10, 9, 11, 12, 6, 5, 7, 8, 2, 1, 3, 4}, - {0, 2, 1, 3, 4, 10, 9, 12, 11, 6, 5, 8, 7} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + { 0, 12, 11, 1, 9, 8, 4, 6, 2, 7, 3, 5, 10}, + { 0, 2, 7, 9, 5, 10, 12, 11, 4, 6, 8, 1, 3}, + { 0, 10, 3, 8, 7, 6, 11, 1, 9, 2, 4, 12, 5}, + { 0, 7, 9, 2, 10, 12, 5, 4, 3, 8, 1, 6, 11}, + { 0, 11, 1, 12, 8, 4, 9, 2, 10, 3, 5, 7, 6}, + { 0, 3, 8, 10, 6, 11, 7, 9, 5, 4, 12, 2, 1}, + { 0, 3, 1, 2, 6, 4, 5, 12, 7, 11, 9, 10, 8}, + { 0, 11, 6, 7, 8, 3, 10, 5, 9, 4, 2, 12, 1}, + { 0, 5, 12, 10, 2, 9, 7, 11, 3, 1, 8, 6, 4}, + { 0, 6, 7, 11, 3, 10, 8, 9, 1, 2, 12, 4, 5}, + { 0, 8, 9, 4, 11, 12, 1, 2, 6, 7, 5, 3, 10}, + { 0, 9, 4, 8, 12, 1, 11, 6, 10, 5, 3, 7, 2}, + { 0, 12, 10, 5, 9, 7, 2, 3, 4, 8, 6, 1, 11}, + { 0, 2, 3, 1, 5, 6, 4, 8, 12, 10, 11, 9, 7}, + { 0, 10, 5, 12, 7, 2, 9, 4, 11, 6, 1, 8, 3}, + { 0, 1, 12, 11, 4, 9, 8, 10, 6, 5, 7, 3, 2}, + { 0, 8, 10, 3, 11, 7, 6, 5, 1, 12, 2, 4, 9}, + { 0, 5, 4, 6, 2, 1, 3, 8, 7, 9, 11, 10, 12}, + { 0, 4, 6, 5, 1, 3, 2, 7, 12, 11, 10, 9, 8}, + { 0, 7, 11, 6, 10, 8, 3, 1, 5, 12, 4, 2, 9}, + { 0, 9, 2, 7, 12, 5, 10, 3, 11, 1, 6, 8, 4}, + { 0, 6, 5, 4, 3, 2, 1, 12, 8, 10, 9, 11, 7}, + { 0, 4, 8, 9, 1, 11, 12, 10, 2, 3, 7, 5, 6}, + }; + +//----------------------------------------------------------------------------- +// bcc +//----------------------------------------------------------------------------- const int8_t mapping_bcc[NUM_CUBIC_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, - {0, 4, 3, 2, 1, 7, 8, 5, 6, 10, 9, 12, 11, 13, 14}, - {0, 6, 5, 7, 8, 2, 1, 3, 4, 10, 9, 11, 12, 14, 13}, - {0, 8, 7, 5, 6, 3, 4, 2, 1, 9, 10, 12, 11, 14, 13}, - {0, 1, 2, 7, 8, 3, 4, 5, 6, 11, 12, 13, 14, 9, 10}, - {0, 4, 3, 7, 8, 5, 6, 2, 1, 13, 14, 10, 9, 12, 11}, - {0, 8, 7, 3, 4, 2, 1, 5, 6, 14, 13, 9, 10, 12, 11}, - {0, 4, 3, 5, 6, 2, 1, 7, 8, 12, 11, 13, 14, 10, 9}, - {0, 1, 2, 5, 6, 7, 8, 3, 4, 13, 14, 9, 10, 11, 12}, - {0, 8, 7, 2, 1, 5, 6, 3, 4, 12, 11, 14, 13, 9, 10}, - {0, 6, 5, 3, 4, 7, 8, 2, 1, 11, 12, 14, 13, 10, 9}, - {0, 6, 5, 2, 1, 3, 4, 7, 8, 14, 13, 10, 9, 11, 12}, - {0, 7, 8, 6, 5, 1, 2, 4, 3, 11, 12, 10, 9, 13, 14}, - {0, 3, 4, 6, 5, 8, 7, 1, 2, 14, 13, 11, 12, 9, 10}, - {0, 5, 6, 1, 2, 8, 7, 4, 3, 9, 10, 13, 14, 12, 11}, - {0, 5, 6, 8, 7, 4, 3, 1, 2, 12, 11, 9, 10, 13, 14}, - {0, 7, 8, 1, 2, 4, 3, 6, 5, 13, 14, 11, 12, 10, 9}, - {0, 3, 4, 8, 7, 1, 2, 6, 5, 9, 10, 14, 13, 11, 12}, - {0, 7, 8, 4, 3, 6, 5, 1, 2, 10, 9, 13, 14, 11, 12}, - {0, 5, 6, 4, 3, 1, 2, 8, 7, 13, 14, 12, 11, 9, 10}, - {0, 3, 4, 1, 2, 6, 5, 8, 7, 11, 12, 9, 10, 14, 13}, - {0, 2, 1, 6, 5, 4, 3, 8, 7, 10, 9, 14, 13, 12, 11}, - {0, 2, 1, 8, 7, 6, 5, 4, 3, 14, 13, 12, 11, 10, 9}, - {0, 2, 1, 4, 3, 8, 7, 6, 5, 12, 11, 10, 9, 14, 13} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, + { 0, 3, 6, 8, 2, 1, 7, 4, 5, 9, 10, 14, 13, 11, 12}, + { 0, 2, 6, 1, 7, 4, 3, 8, 5, 13, 14, 11, 12, 10, 9}, + { 0, 5, 1, 8, 2, 4, 3, 6, 7, 12, 11, 9, 10, 13, 14}, + { 0, 2, 4, 6, 5, 1, 7, 8, 3, 11, 12, 10, 9, 13, 14}, + { 0, 3, 1, 6, 5, 8, 2, 4, 7, 14, 13, 11, 12, 9, 10}, + { 0, 5, 4, 1, 7, 8, 2, 6, 3, 9, 10, 13, 14, 12, 11}, + { 0, 1, 3, 5, 6, 2, 8, 7, 4, 13, 14, 9, 10, 11, 12}, + { 0, 6, 7, 3, 4, 2, 8, 5, 1, 11, 12, 14, 13, 10, 9}, + { 0, 8, 3, 7, 1, 5, 6, 2, 4, 12, 11, 14, 13, 9, 10}, + { 0, 6, 2, 7, 1, 3, 4, 5, 8, 14, 13, 10, 9, 11, 12}, + { 0, 4, 2, 5, 6, 7, 1, 3, 8, 12, 11, 13, 14, 10, 9}, + { 0, 4, 7, 2, 8, 5, 6, 3, 1, 13, 14, 10, 9, 12, 11}, + { 0, 8, 5, 3, 4, 7, 1, 2, 6, 14, 13, 9, 10, 12, 11}, + { 0, 1, 5, 2, 8, 3, 4, 7, 6, 11, 12, 13, 14, 9, 10}, + { 0, 8, 7, 5, 6, 3, 4, 2, 1, 9, 10, 12, 11, 14, 13}, + { 0, 3, 8, 1, 7, 6, 5, 4, 2, 11, 12, 9, 10, 14, 13}, + { 0, 5, 8, 4, 3, 1, 7, 6, 2, 13, 14, 12, 11, 9, 10}, + { 0, 7, 4, 8, 2, 6, 5, 1, 3, 14, 13, 12, 11, 10, 9}, + { 0, 7, 6, 4, 3, 8, 2, 1, 5, 12, 11, 10, 9, 14, 13}, + { 0, 6, 3, 2, 8, 7, 1, 5, 4, 10, 9, 11, 12, 14, 13}, + { 0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 13, 14, 11, 12}, + { 0, 7, 8, 6, 5, 4, 3, 1, 2, 10, 9, 14, 13, 12, 11}, + { 0, 4, 5, 7, 1, 2, 8, 3, 6, 10, 9, 12, 11, 13, 14}, + }; + +//----------------------------------------------------------------------------- +// ico +//----------------------------------------------------------------------------- const int8_t mapping_ico[NUM_ICO_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, - {0, 10, 9, 8, 7, 5, 6, 2, 1, 12, 11, 3, 4}, - {0, 1, 2, 9, 10, 7, 8, 11, 12, 5, 6, 3, 4}, - {0, 4, 3, 8, 7, 2, 1, 11, 12, 9, 10, 6, 5}, - {0, 6, 5, 9, 10, 4, 3, 7, 8, 12, 11, 2, 1}, - {0, 12, 11, 3, 4, 7, 8, 10, 9, 2, 1, 6, 5}, - {0, 4, 3, 6, 5, 9, 10, 2, 1, 8, 7, 11, 12}, - {0, 8, 7, 2, 1, 4, 3, 10, 9, 5, 6, 11, 12}, - {0, 10, 9, 3, 4, 12, 11, 5, 6, 8, 7, 2, 1}, - {0, 12, 11, 6, 5, 2, 1, 7, 8, 3, 4, 10, 9}, - {0, 1, 2, 11, 12, 9, 10, 5, 6, 3, 4, 7, 8}, - {0, 8, 7, 11, 12, 5, 6, 4, 3, 2, 1, 10, 9}, - {0, 6, 5, 2, 1, 12, 11, 4, 3, 9, 10, 7, 8}, - {0, 3, 4, 5, 6, 1, 2, 10, 9, 12, 11, 7, 8}, - {0, 3, 4, 7, 8, 12, 11, 1, 2, 5, 6, 10, 9}, - {0, 6, 5, 7, 8, 9, 10, 12, 11, 2, 1, 4, 3}, - {0, 9, 10, 11, 12, 4, 3, 1, 2, 7, 8, 6, 5}, - {0, 11, 12, 9, 10, 1, 2, 4, 3, 8, 7, 5, 6}, - {0, 8, 7, 5, 6, 10, 9, 11, 12, 4, 3, 2, 1}, - {0, 10, 9, 2, 1, 8, 7, 12, 11, 3, 4, 5, 6}, - {0, 12, 11, 2, 1, 10, 9, 6, 5, 7, 8, 3, 4}, - {0, 9, 10, 6, 5, 7, 8, 4, 3, 11, 12, 1, 2}, - {0, 8, 7, 10, 9, 2, 1, 5, 6, 11, 12, 4, 3}, - {0, 6, 5, 12, 11, 7, 8, 2, 1, 4, 3, 9, 10}, - {0, 11, 12, 8, 7, 4, 3, 5, 6, 1, 2, 9, 10}, - {0, 4, 3, 11, 12, 8, 7, 9, 10, 6, 5, 2, 1}, - {0, 4, 3, 9, 10, 11, 12, 6, 5, 2, 1, 8, 7}, - {0, 12, 11, 10, 9, 3, 4, 2, 1, 6, 5, 7, 8}, - {0, 5, 6, 8, 7, 11, 12, 10, 9, 3, 4, 1, 2}, - {0, 7, 8, 6, 5, 12, 11, 9, 10, 1, 2, 3, 4}, - {0, 10, 9, 12, 11, 2, 1, 3, 4, 5, 6, 8, 7}, - {0, 7, 8, 1, 2, 9, 10, 3, 4, 12, 11, 6, 5}, - {0, 5, 6, 1, 2, 3, 4, 11, 12, 8, 7, 10, 9}, - {0, 7, 8, 12, 11, 3, 4, 6, 5, 9, 10, 1, 2}, - {0, 1, 2, 5, 6, 11, 12, 3, 4, 7, 8, 9, 10}, - {0, 11, 12, 1, 2, 5, 6, 9, 10, 4, 3, 8, 7}, - {0, 5, 6, 3, 4, 10, 9, 1, 2, 11, 12, 8, 7}, - {0, 5, 6, 10, 9, 8, 7, 3, 4, 1, 2, 11, 12}, - {0, 3, 4, 12, 11, 10, 9, 7, 8, 1, 2, 5, 6}, - {0, 9, 10, 7, 8, 1, 2, 6, 5, 4, 3, 11, 12}, - {0, 9, 10, 1, 2, 11, 12, 7, 8, 6, 5, 4, 3}, - {0, 7, 8, 3, 4, 1, 2, 12, 11, 6, 5, 9, 10}, - {0, 11, 12, 5, 6, 8, 7, 1, 2, 9, 10, 4, 3}, - {0, 1, 2, 7, 8, 3, 4, 9, 10, 11, 12, 5, 6}, - {0, 3, 4, 10, 9, 5, 6, 12, 11, 7, 8, 1, 2}, - {0, 2, 1, 4, 3, 8, 7, 6, 5, 12, 11, 10, 9}, - {0, 2, 1, 12, 11, 6, 5, 10, 9, 8, 7, 4, 3}, - {0, 9, 10, 4, 3, 6, 5, 11, 12, 1, 2, 7, 8}, - {0, 11, 12, 4, 3, 9, 10, 8, 7, 5, 6, 1, 2}, - {0, 2, 1, 10, 9, 12, 11, 8, 7, 4, 3, 6, 5}, - {0, 5, 6, 11, 12, 1, 2, 8, 7, 10, 9, 3, 4}, - {0, 10, 9, 5, 6, 3, 4, 8, 7, 2, 1, 12, 11}, - {0, 12, 11, 7, 8, 6, 5, 3, 4, 10, 9, 2, 1}, - {0, 7, 8, 9, 10, 6, 5, 1, 2, 3, 4, 12, 11}, - {0, 2, 1, 8, 7, 10, 9, 4, 3, 6, 5, 12, 11}, - {0, 8, 7, 4, 3, 11, 12, 2, 1, 10, 9, 5, 6}, - {0, 6, 5, 4, 3, 2, 1, 9, 10, 7, 8, 12, 11}, - {0, 2, 1, 6, 5, 4, 3, 12, 11, 10, 9, 8, 7}, - {0, 3, 4, 1, 2, 7, 8, 5, 6, 10, 9, 12, 11}, - {0, 4, 3, 2, 1, 6, 5, 8, 7, 11, 12, 9, 10} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + { 0, 6, 5, 2, 1, 12, 11, 4, 3, 9, 10, 7, 8}, + { 0, 6, 5, 9, 10, 4, 3, 7, 8, 12, 11, 2, 1}, + { 0, 8, 7, 2, 1, 4, 3, 10, 9, 5, 6, 11, 12}, + { 0, 10, 9, 3, 4, 12, 11, 5, 6, 8, 7, 2, 1}, + { 0, 8, 7, 11, 12, 5, 6, 4, 3, 2, 1, 10, 9}, + { 0, 1, 2, 11, 12, 9, 10, 5, 6, 3, 4, 7, 8}, + { 0, 1, 2, 9, 10, 7, 8, 11, 12, 5, 6, 3, 4}, + { 0, 10, 9, 8, 7, 5, 6, 2, 1, 12, 11, 3, 4}, + { 0, 12, 11, 3, 4, 7, 8, 10, 9, 2, 1, 6, 5}, + { 0, 4, 3, 6, 5, 9, 10, 2, 1, 8, 7, 11, 12}, + { 0, 12, 11, 6, 5, 2, 1, 7, 8, 3, 4, 10, 9}, + { 0, 4, 3, 8, 7, 2, 1, 11, 12, 9, 10, 6, 5}, + { 0, 3, 4, 5, 6, 1, 2, 10, 9, 12, 11, 7, 8}, + { 0, 11, 12, 9, 10, 1, 2, 4, 3, 8, 7, 5, 6}, + { 0, 3, 4, 7, 8, 12, 11, 1, 2, 5, 6, 10, 9}, + { 0, 8, 7, 5, 6, 10, 9, 11, 12, 4, 3, 2, 1}, + { 0, 10, 9, 2, 1, 8, 7, 12, 11, 3, 4, 5, 6}, + { 0, 11, 12, 8, 7, 4, 3, 5, 6, 1, 2, 9, 10}, + { 0, 6, 5, 7, 8, 9, 10, 12, 11, 2, 1, 4, 3}, + { 0, 6, 5, 12, 11, 7, 8, 2, 1, 4, 3, 9, 10}, + { 0, 9, 10, 11, 12, 4, 3, 1, 2, 7, 8, 6, 5}, + { 0, 12, 11, 2, 1, 10, 9, 6, 5, 7, 8, 3, 4}, + { 0, 4, 3, 11, 12, 8, 7, 9, 10, 6, 5, 2, 1}, + { 0, 7, 8, 6, 5, 12, 11, 9, 10, 1, 2, 3, 4}, + { 0, 8, 7, 10, 9, 2, 1, 5, 6, 11, 12, 4, 3}, + { 0, 10, 9, 12, 11, 2, 1, 3, 4, 5, 6, 8, 7}, + { 0, 9, 10, 6, 5, 7, 8, 4, 3, 11, 12, 1, 2}, + { 0, 4, 3, 9, 10, 11, 12, 6, 5, 2, 1, 8, 7}, + { 0, 12, 11, 10, 9, 3, 4, 2, 1, 6, 5, 7, 8}, + { 0, 7, 8, 1, 2, 9, 10, 3, 4, 12, 11, 6, 5}, + { 0, 5, 6, 8, 7, 11, 12, 10, 9, 3, 4, 1, 2}, + { 0, 5, 6, 1, 2, 3, 4, 11, 12, 8, 7, 10, 9}, + { 0, 11, 12, 5, 6, 8, 7, 1, 2, 9, 10, 4, 3}, + { 0, 3, 4, 12, 11, 10, 9, 7, 8, 1, 2, 5, 6}, + { 0, 9, 10, 7, 8, 1, 2, 6, 5, 4, 3, 11, 12}, + { 0, 7, 8, 3, 4, 1, 2, 12, 11, 6, 5, 9, 10}, + { 0, 3, 4, 10, 9, 5, 6, 12, 11, 7, 8, 1, 2}, + { 0, 1, 2, 7, 8, 3, 4, 9, 10, 11, 12, 5, 6}, + { 0, 1, 2, 5, 6, 11, 12, 3, 4, 7, 8, 9, 10}, + { 0, 11, 12, 1, 2, 5, 6, 9, 10, 4, 3, 8, 7}, + { 0, 5, 6, 3, 4, 10, 9, 1, 2, 11, 12, 8, 7}, + { 0, 5, 6, 10, 9, 8, 7, 3, 4, 1, 2, 11, 12}, + { 0, 9, 10, 1, 2, 11, 12, 7, 8, 6, 5, 4, 3}, + { 0, 7, 8, 12, 11, 3, 4, 6, 5, 9, 10, 1, 2}, + { 0, 2, 1, 12, 11, 6, 5, 10, 9, 8, 7, 4, 3}, + { 0, 2, 1, 4, 3, 8, 7, 6, 5, 12, 11, 10, 9}, + { 0, 9, 10, 4, 3, 6, 5, 11, 12, 1, 2, 7, 8}, + { 0, 7, 8, 9, 10, 6, 5, 1, 2, 3, 4, 12, 11}, + { 0, 2, 1, 8, 7, 10, 9, 4, 3, 6, 5, 12, 11}, + { 0, 11, 12, 4, 3, 9, 10, 8, 7, 5, 6, 1, 2}, + { 0, 10, 9, 5, 6, 3, 4, 8, 7, 2, 1, 12, 11}, + { 0, 8, 7, 4, 3, 11, 12, 2, 1, 10, 9, 5, 6}, + { 0, 3, 4, 1, 2, 7, 8, 5, 6, 10, 9, 12, 11}, + { 0, 2, 1, 10, 9, 12, 11, 8, 7, 4, 3, 6, 5}, + { 0, 12, 11, 7, 8, 6, 5, 3, 4, 10, 9, 2, 1}, + { 0, 4, 3, 2, 1, 6, 5, 8, 7, 11, 12, 9, 10}, + { 0, 2, 1, 6, 5, 4, 3, 12, 11, 10, 9, 8, 7}, + { 0, 5, 6, 11, 12, 1, 2, 8, 7, 10, 9, 3, 4}, + { 0, 6, 5, 4, 3, 2, 1, 9, 10, 7, 8, 12, 11}, +}; + +//----------------------------------------------------------------------------- +// hcp +//----------------------------------------------------------------------------- const int8_t mapping_hcp[NUM_HEX_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, - {0, 5, 6, 1, 2, 3, 4, 9, 10, 12, 11, 8, 7}, - {0, 3, 4, 5, 6, 1, 2, 12, 11, 7, 8, 10, 9}, - {0, 4, 3, 2, 1, 6, 5, 11, 12, 10, 9, 7, 8}, - {0, 2, 1, 6, 5, 4, 3, 8, 7, 11, 12, 9, 10}, - {0, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 12, 11} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + { 0, 2, 7, 4, 5, 3, 8, 1, 9, 6, 12, 10, 11}, + { 0, 7, 1, 5, 3, 4, 9, 2, 6, 8, 11, 12, 10}, + { 0, 6, 9, 10, 11, 12, 1, 8, 7, 2, 3, 4, 5}, + { 0, 8, 6, 12, 10, 11, 2, 9, 1, 7, 4, 5, 3}, + { 0, 9, 8, 11, 12, 10, 7, 6, 2, 1, 5, 3, 4}, +}; + +const int8_t template_indices_hcp[NUM_CONVENTIONAL_HEX_MAPPINGS] = {0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1}; + +const int8_t mapping_hcp_conventional[NUM_CONVENTIONAL_HEX_MAPPINGS][PTM_MAX_POINTS] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + { 0, 2, 7, 4, 5, 3, 8, 1, 9, 6, 12, 10, 11}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + { 0, 2, 7, 4, 5, 3, 8, 1, 9, 6, 12, 10, 11}, + { 0, 7, 1, 5, 3, 4, 9, 2, 6, 8, 11, 12, 10}, + { 0, 8, 6, 12, 10, 11, 2, 9, 1, 7, 4, 5, 3}, + { 0, 6, 9, 10, 11, 12, 1, 8, 7, 2, 3, 4, 5}, + { 0, 8, 6, 12, 10, 11, 2, 9, 1, 7, 4, 5, 3}, + { 0, 6, 9, 10, 11, 12, 1, 8, 7, 2, 3, 4, 5}, + { 0, 9, 8, 11, 12, 10, 7, 6, 2, 1, 5, 3, 4}, + { 0, 9, 8, 11, 12, 10, 7, 6, 2, 1, 5, 3, 4}, + { 0, 7, 1, 5, 3, 4, 9, 2, 6, 8, 11, 12, 10}, +}; + +//----------------------------------------------------------------------------- +// dcub +//----------------------------------------------------------------------------- const int8_t mapping_dcub[NUM_DCUB_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - {0, 2, 1, 4, 3, 9, 8, 10, 6, 5, 7, 14, 16, 15, 11, 13, 12}, - {0, 4, 3, 2, 1, 15, 16, 14, 12, 13, 11, 10, 8, 9, 7, 5, 6}, - {0, 3, 4, 1, 2, 13, 12, 11, 16, 15, 14, 7, 6, 5, 10, 9, 8}, - {0, 4, 2, 1, 3, 14, 15, 16, 9, 10, 8, 6, 5, 7, 12, 11, 13}, - {0, 4, 1, 3, 2, 16, 14, 15, 7, 6, 5, 13, 11, 12, 9, 8, 10}, - {0, 1, 4, 2, 3, 6, 7, 5, 14, 16, 15, 9, 10, 8, 13, 12, 11}, - {0, 3, 1, 2, 4, 11, 13, 12, 5, 7, 6, 8, 9, 10, 16, 14, 15}, - {0, 3, 2, 4, 1, 12, 11, 13, 10, 8, 9, 15, 14, 16, 5, 6, 7}, - {0, 2, 4, 3, 1, 10, 9, 8, 15, 14, 16, 12, 13, 11, 6, 7, 5}, - {0, 1, 3, 4, 2, 7, 5, 6, 13, 11, 12, 16, 15, 14, 8, 10, 9}, - {0, 2, 3, 1, 4, 8, 10, 9, 11, 12, 13, 5, 7, 6, 15, 16, 14} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 1, 3, 4, 2, 7, 5, 6, 11, 13, 12, 14, 15, 16, 8, 10, 9}, + { 0, 4, 1, 3, 2, 16, 14, 15, 7, 6, 5, 12, 13, 11, 9, 8, 10}, + { 0, 2, 3, 1, 4, 8, 10, 9, 13, 12, 11, 6, 7, 5, 15, 16, 14}, + { 0, 4, 2, 1, 3, 14, 15, 16, 9, 10, 8, 7, 5, 6, 12, 13, 11}, + { 0, 3, 2, 4, 1, 12, 13, 11, 10, 8, 9, 16, 14, 15, 5, 6, 7}, + { 0, 3, 1, 2, 4, 13, 11, 12, 5, 7, 6, 10, 9, 8, 16, 14, 15}, + { 0, 2, 4, 3, 1, 10, 9, 8, 15, 14, 16, 13, 11, 12, 6, 7, 5}, + { 0, 1, 4, 2, 3, 6, 7, 5, 14, 16, 15, 8, 10, 9, 11, 12, 13}, + { 0, 2, 1, 4, 3, 9, 8, 10, 6, 5, 7, 15, 16, 14, 13, 11, 12}, + { 0, 4, 3, 2, 1, 15, 16, 14, 12, 11, 13, 9, 8, 10, 7, 5, 6}, + { 0, 3, 4, 1, 2, 11, 12, 13, 16, 15, 14, 5, 6, 7, 10, 9, 8}, +}; + +const int8_t template_indices_dcub[NUM_CONVENTIONAL_DCUB_MAPPINGS] = {0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0}; + +const int8_t mapping_dcub_conventional[NUM_CONVENTIONAL_DCUB_MAPPINGS][PTM_MAX_POINTS] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 2, 1, 4, 3, 9, 8, 10, 6, 5, 7, 15, 16, 14, 13, 11, 12}, + { 0, 4, 1, 3, 2, 16, 14, 15, 7, 6, 5, 12, 13, 11, 9, 8, 10}, + { 0, 1, 3, 4, 2, 7, 5, 6, 11, 13, 12, 14, 15, 16, 8, 10, 9}, + { 0, 4, 2, 1, 3, 14, 15, 16, 9, 10, 8, 7, 5, 6, 12, 13, 11}, + { 0, 2, 3, 1, 4, 8, 10, 9, 13, 12, 11, 6, 7, 5, 15, 16, 14}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 1, 3, 4, 2, 7, 5, 6, 11, 13, 12, 14, 15, 16, 8, 10, 9}, + { 0, 4, 1, 3, 2, 16, 14, 15, 7, 6, 5, 12, 13, 11, 9, 8, 10}, + { 0, 2, 3, 1, 4, 8, 10, 9, 13, 12, 11, 6, 7, 5, 15, 16, 14}, + { 0, 4, 2, 1, 3, 14, 15, 16, 9, 10, 8, 7, 5, 6, 12, 13, 11}, + { 0, 3, 2, 4, 1, 12, 13, 11, 10, 8, 9, 16, 14, 15, 5, 6, 7}, + { 0, 3, 1, 2, 4, 13, 11, 12, 5, 7, 6, 10, 9, 8, 16, 14, 15}, + { 0, 2, 4, 3, 1, 10, 9, 8, 15, 14, 16, 13, 11, 12, 6, 7, 5}, + { 0, 1, 4, 2, 3, 6, 7, 5, 14, 16, 15, 8, 10, 9, 11, 12, 13}, + { 0, 2, 1, 4, 3, 9, 8, 10, 6, 5, 7, 15, 16, 14, 13, 11, 12}, + { 0, 2, 4, 3, 1, 10, 9, 8, 15, 14, 16, 13, 11, 12, 6, 7, 5}, + { 0, 1, 4, 2, 3, 6, 7, 5, 14, 16, 15, 8, 10, 9, 11, 12, 13}, + { 0, 3, 2, 4, 1, 12, 13, 11, 10, 8, 9, 16, 14, 15, 5, 6, 7}, + { 0, 3, 1, 2, 4, 13, 11, 12, 5, 7, 6, 10, 9, 8, 16, 14, 15}, + { 0, 4, 3, 2, 1, 15, 16, 14, 12, 11, 13, 9, 8, 10, 7, 5, 6}, + { 0, 4, 3, 2, 1, 15, 16, 14, 12, 11, 13, 9, 8, 10, 7, 5, 6}, + { 0, 3, 4, 1, 2, 11, 12, 13, 16, 15, 14, 5, 6, 7, 10, 9, 8}, + { 0, 3, 4, 1, 2, 11, 12, 13, 16, 15, 14, 5, 6, 7, 10, 9, 8}, +}; + +//----------------------------------------------------------------------------- +// dhex +//----------------------------------------------------------------------------- const int8_t mapping_dhex[NUM_DHEX_MAPPINGS][PTM_MAX_POINTS] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - {0, 1, 3, 4, 2, 6, 7, 5, 11, 13, 12, 14, 16, 15, 8, 9, 10}, - {0, 1, 4, 2, 3, 7, 5, 6, 14, 15, 16, 8, 10, 9, 11, 13, 12} }; + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 3, 1, 2, 4, 12, 11, 13, 5, 6, 7, 9, 8, 10, 16, 14, 15}, + { 0, 2, 3, 1, 4, 8, 9, 10, 12, 11, 13, 6, 5, 7, 15, 16, 14}, +}; + +const int8_t template_indices_dhex[NUM_CONVENTIONAL_DHEX_MAPPINGS] = {0, 1, 1, 0, 0, 3, 2, 2, 3, 3, 2, 1}; + +const int8_t mapping_dhex_conventional[NUM_CONVENTIONAL_DHEX_MAPPINGS][PTM_MAX_POINTS] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 3, 1, 2, 4, 12, 11, 13, 5, 6, 7, 9, 8, 10, 16, 14, 15}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 3, 1, 2, 4, 12, 11, 13, 5, 6, 7, 9, 8, 10, 16, 14, 15}, + { 0, 2, 3, 1, 4, 8, 9, 10, 12, 11, 13, 6, 5, 7, 15, 16, 14}, + { 0, 2, 3, 1, 4, 8, 9, 10, 12, 11, 13, 6, 5, 7, 15, 16, 14}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 2, 3, 1, 4, 8, 9, 10, 12, 11, 13, 6, 5, 7, 15, 16, 14}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + { 0, 3, 1, 2, 4, 12, 11, 13, 5, 6, 7, 9, 8, 10, 16, 14, 15}, + { 0, 3, 1, 2, 4, 12, 11, 13, 5, 6, 7, 9, 8, 10, 16, 14, 15}, + { 0, 2, 3, 1, 4, 8, 9, 10, 12, 11, 13, 6, 5, 7, 15, 16, 14}, +}; + +//----------------------------------------------------------------------------- +// graphene +//----------------------------------------------------------------------------- + +const int8_t mapping_graphene[NUM_GRAPHENE_MAPPINGS][PTM_MAX_POINTS] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + { 0, 2, 3, 1, 6, 7, 8, 9, 4, 5}, + { 0, 3, 1, 2, 8, 9, 4, 5, 6, 7}, + { 0, 2, 1, 3, 7, 6, 5, 4, 9, 8}, + { 0, 3, 2, 1, 9, 8, 7, 6, 5, 4}, + { 0, 1, 3, 2, 5, 4, 9, 8, 7, 6}, +}; + +const int8_t template_indices_graphene[NUM_CONVENTIONAL_GRAPHENE_MAPPINGS] = {0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1}; + +const int8_t mapping_graphene_conventional[NUM_CONVENTIONAL_GRAPHENE_MAPPINGS][PTM_MAX_POINTS] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + { 0, 2, 3, 1, 6, 7, 8, 9, 4, 5}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + { 0, 2, 3, 1, 6, 7, 8, 9, 4, 5}, + { 0, 3, 1, 2, 8, 9, 4, 5, 6, 7}, + { 0, 3, 2, 1, 9, 8, 7, 6, 5, 4}, + { 0, 2, 1, 3, 7, 6, 5, 4, 9, 8}, + { 0, 3, 2, 1, 9, 8, 7, 6, 5, 4}, + { 0, 2, 1, 3, 7, 6, 5, 4, 9, 8}, + { 0, 1, 3, 2, 5, 4, 9, 8, 7, 6}, + { 0, 1, 3, 2, 5, 4, 9, 8, 7, 6}, + { 0, 3, 1, 2, 8, 9, 4, 5, 6, 7}, +}; + } #endif diff --git a/src/USER-PTM/ptm_graph_data.cpp b/src/USER-PTM/ptm_graph_data.cpp index a742c8b339..f6d07f879c 100644 --- a/src/USER-PTM/ptm_graph_data.cpp +++ b/src/USER-PTM/ptm_graph_data.cpp @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include "ptm_graph_data.h" @@ -6,69 +15,69 @@ namespace ptm { int8_t automorphisms[65][17] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 4, 3, 10, 9, 5, 6, 12, 11, 8, 7, 1, 2, -1, -1, -1, -1}, - { 0, 5, 6, 11, 12, 8, 7, 2, 1, 4, 3, 10, 9, -1, -1, -1, -1}, - { 0, 8, 7, 1, 2, 4, 3, 9, 10, 5, 6, 11, 12, -1, -1, -1, -1}, - { 0, 8, 7, 10, 9, 1, 2, 6, 5, 12, 11, 3, 4, -1, -1, -1, -1}, + { 0, 1, 11, 7, 4, 8, 10, 12, 6, 5, 9, 3, 2, -1, -1, -1, -1}, + { 0, 5, 4, 6, 2, 1, 3, 10, 9, 8, 7, 12, 11, -1, -1, -1, -1}, + { 0, 7, 1, 11, 10, 4, 8, 2, 12, 3, 5, 9, 6, -1, -1, -1, -1}, + { 0, 11, 7, 1, 8, 10, 4, 6, 2, 9, 3, 5, 12, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 12, 3, 2, 7, 10, 8, 4, 6, 11, 5, 9, 1, -1, -1, -1, -1}, + { 0, 6, 5, 9, 10, 2, 1, 11, 12, 3, 4, 7, 8, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 4, 11, 8, 1, 9, 12, 10, 3, 5, 7, 2, 6, -1, -1, -1, -1}, + { 0, 1, 3, 4, 7, 8, 6, 12, 11, 5, 9, 10, 2, -1, -1, -1, -1}, + { 0, 1, 4, 7, 12, 11, 6, 2, 10, 8, 5, 9, 3, -1, -1, -1, -1}, + { 0, 8, 3, 6, 12, 7, 2, 10, 11, 4, 5, 1, 9, -1, -1, -1, -1}, + { 0, 9, 6, 4, 8, 5, 7, 11, 1, 3, 2, 10, 12, -1, -1, -1, -1}, + { 0, 10, 6, 3, 5, 9, 4, 8, 1, 2, 12, 11, 7, -1, -1, -1, -1}, + { 0, 10, 7, 6, 3, 2, 4, 5, 9, 12, 11, 1, 8, -1, -1, -1, -1}, + { 0, 11, 4, 6, 2, 12, 3, 9, 10, 7, 8, 1, 5, -1, -1, -1, -1}, + { 0, 11, 6, 2, 9, 10, 3, 5, 1, 12, 7, 8, 4, -1, -1, -1, -1}, + { 0, 12, 4, 3, 9, 2, 5, 1, 10, 6, 7, 11, 8, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 2, 1, 6, 5, 4, 3, 9, 8, 7, 11, 10, 12, -1, -1, -1, -1}, + { 0, 12, 8, 7, 6, 11, 4, 3, 2, 10, 9, 5, 1, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 1, 7, 10, 11, 9, 6, 4, 2, 12, 5, 8, 3, -1, -1, -1, -1}, - { 0, 1, 11, 9, 2, 3, 6, 8, 4, 10, 12, 7, 5, -1, -1, -1, -1}, - { 0, 3, 6, 1, 11, 9, 2, 10, 12, 5, 7, 4, 8, -1, -1, -1, -1}, - { 0, 3, 11, 9, 12, 8, 2, 4, 10, 1, 5, 6, 7, -1, -1, -1, -1}, - { 0, 8, 2, 3, 11, 9, 12, 1, 5, 7, 6, 10, 4, -1, -1, -1, -1}, - { 0, 9, 2, 3, 6, 1, 11, 5, 7, 8, 4, 12, 10, -1, -1, -1, -1}, - { 0, 9, 6, 1, 7, 10, 11, 12, 5, 3, 8, 2, 4, -1, -1, -1, -1}, - { 0, 9, 12, 8, 2, 3, 11, 7, 6, 4, 10, 5, 1, -1, -1, -1, -1}, - { 0, 10, 11, 9, 6, 1, 7, 3, 8, 4, 2, 5, 12, -1, -1, -1, -1}, + { 0, 1, 7, 11, 12, 10, 6, 2, 9, 8, 5, 3, 4, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1}, - { 0, 3, 2, 8, 6, 5, 12, 11, 7, 4, 9, 1, 10, -1, -1, -1, -1}, - { 0, 3, 11, 10, 6, 9, 7, 4, 2, 12, 1, 8, 5, -1, -1, -1, -1}, - { 0, 3, 12, 9, 6, 8, 11, 7, 4, 2, 10, 5, 1, -1, -1, -1, -1}, - { 0, 5, 12, 3, 2, 8, 6, 4, 9, 10, 1, 7, 11, -1, -1, -1, -1}, - { 0, 8, 6, 5, 12, 3, 2, 10, 1, 11, 7, 9, 4, -1, -1, -1, -1}, - { 0, 8, 11, 3, 12, 9, 6, 2, 10, 1, 5, 4, 7, -1, -1, -1, -1}, - { 0, 9, 6, 8, 11, 3, 12, 1, 5, 7, 4, 10, 2, -1, -1, -1, -1}, - { 0, 9, 7, 3, 11, 10, 6, 12, 1, 5, 8, 2, 4, -1, -1, -1, -1}, - { 0, 10, 6, 9, 7, 3, 11, 5, 8, 4, 2, 1, 12, -1, -1, -1, -1}, + { 0, 1, 3, 7, 8, 4, 6, 11, 10, 5, 9, 12, 2, -1, -1, -1, -1}, + { 0, 8, 3, 6, 11, 7, 2, 12, 10, 4, 1, 9, 5, -1, -1, -1, -1}, + { 0, 9, 3, 4, 1, 5, 7, 8, 10, 2, 12, 11, 6, -1, -1, -1, -1}, + { 0, 9, 6, 3, 5, 2, 7, 4, 1, 12, 10, 8, 11, -1, -1, -1, -1}, + { 0, 10, 4, 7, 11, 8, 3, 6, 12, 1, 9, 2, 5, -1, -1, -1, -1}, + { 0, 10, 6, 2, 9, 12, 3, 5, 1, 11, 8, 4, 7, -1, -1, -1, -1}, + { 0, 10, 7, 6, 12, 11, 3, 2, 9, 8, 1, 5, 4, -1, -1, -1, -1}, + { 0, 11, 4, 3, 6, 7, 5, 2, 12, 8, 10, 9, 1, -1, -1, -1, -1}, + { 0, 12, 7, 3, 2, 6, 4, 5, 9, 11, 10, 1, 8, -1, -1, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 3, 4, 6, 5, 2, 1, 9, 10, 14, 13, 11, 12, 8, 7, -1, -1}, - { 0, 4, 3, 1, 2, 5, 6, 10, 9, 13, 14, 7, 8, 12, 11, -1, -1}, - { 0, 6, 5, 1, 2, 4, 3, 14, 13, 7, 8, 11, 12, 10, 9, -1, -1}, + { 0, 2, 6, 13, 14, 7, 1, 8, 5, 4, 3, 11, 12, 10, 9, -1, -1}, + { 0, 6, 1, 10, 9, 8, 2, 5, 7, 14, 13, 11, 12, 3, 4, -1, -1}, + { 0, 8, 1, 14, 13, 5, 6, 2, 7, 12, 11, 3, 4, 9, 10, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 12, 11, 10, 9, 13, 14, 8, 7, 4, 3, 2, 1, 5, 6, -1, -1}, + { 0, 12, 14, 4, 3, 9, 10, 11, 13, 5, 6, 7, 1, 8, 2, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 9, 10, 13, 14, 11, 12, 8, 7, 1, 2, 5, 6, 3, 4, -1, -1}, + { 0, 13, 9, 4, 3, 11, 12, 14, 10, 2, 8, 5, 6, 1, 7, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 6, 5, 4, 3, 2, 1, 11, 12, 10, 9, 7, 8, 14, 13, -1, -1}, + { 0, 6, 8, 11, 12, 7, 1, 5, 2, 10, 9, 3, 4, 14, 13, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 12, 11, 10, 9, 13, 14, 8, 7, 4, 3, 2, 1, 5, 6, -1, -1}, + { 0, 12, 14, 4, 3, 9, 10, 11, 13, 5, 6, 7, 1, 8, 2, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 9, 10, 13, 14, 11, 12, 8, 7, 1, 2, 5, 6, 3, 4, -1, -1}, + { 0, 13, 9, 4, 3, 11, 12, 14, 10, 2, 8, 5, 6, 1, 7, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 3, 10, 14, 5, 9, 7, 13, 2, 8, 4, 11, 12, 1, 6, -1, -1}, - { 0, 13, 8, 1, 10, 4, 14, 6, 9, 5, 2, 11, 12, 7, 3, -1, -1}, + { 0, 3, 13, 14, 5, 9, 2, 10, 7, 8, 4, 11, 12, 1, 6, -1, -1}, + { 0, 13, 6, 1, 10, 4, 14, 8, 9, 5, 7, 11, 12, 2, 3, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 11, 12, 14, 13, 9, 10, 7, 8, 3, 4, 6, 5, 1, 2, -1, -1}, + { 0, 9, 13, 3, 4, 12, 11, 10, 14, 8, 2, 1, 7, 5, 6, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1}, - { 0, 13, 14, 11, 12, 5, 6, 10, 9, 1, 2, 7, 8, 4, 3, -1, -1}, + { 0, 13, 10, 11, 12, 5, 6, 14, 9, 1, 7, 2, 8, 4, 3, -1, -1}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 0, 4, 3, 2, 1, 15, 14, 16, 13, 12, 11, 10, 9, 8, 6, 5, 7}, + { 0, 2, 1, 4, 3, 9, 10, 8, 7, 5, 6, 14, 15, 16, 11, 12, 13}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 0, 4, 1, 3, 2, 15, 14, 16, 5, 7, 6, 13, 11, 12, 10, 8, 9}, - { 0, 4, 2, 1, 3, 16, 15, 14, 10, 8, 9, 5, 6, 7, 13, 12, 11}, - { 0, 4, 3, 2, 1, 14, 16, 15, 13, 12, 11, 10, 9, 8, 5, 7, 6}, + { 0, 1, 3, 4, 2, 6, 7, 5, 13, 12, 11, 16, 14, 15, 9, 8, 10}, + { 0, 2, 4, 3, 1, 10, 8, 9, 16, 15, 14, 13, 11, 12, 5, 7, 6}, + { 0, 4, 1, 3, 2, 14, 16, 15, 6, 7, 5, 12, 13, 11, 10, 9, 8}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 0, 3, 4, 1, 2, 12, 13, 11, 16, 14, 15, 7, 5, 6, 9, 10, 8}, + { 0, 1, 3, 4, 2, 6, 7, 5, 13, 12, 11, 15, 16, 14, 8, 10, 9}, + { 0, 2, 4, 3, 1, 10, 8, 9, 15, 14, 16, 13, 11, 12, 7, 6, 5}, + { 0, 4, 2, 1, 3, 14, 16, 15, 9, 10, 8, 5, 7, 6, 11, 12, 13}, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 0, 4, 1, 3, 2, 16, 15, 14, 6, 5, 7, 13, 11, 12, 10, 8, 9}, - { 0, 4, 2, 1, 3, 14, 16, 15, 10, 8, 9, 6, 7, 5, 13, 12, 11}, - { 0, 4, 3, 2, 1, 15, 14, 16, 13, 12, 11, 10, 9, 8, 6, 5, 7}, + { 0, 3, 4, 1, 2, 13, 12, 11, 16, 15, 14, 7, 6, 5, 10, 9, 8}, }; graph_t graphs_sc[NUM_SC_GRAPHS] = { @@ -77,7 +86,7 @@ graph_t graphs_sc[NUM_SC_GRAPHS] = { 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0}, {{1,3,4},{1,3,5},{0,3,4},{0,3,5},{1,2,5},{1,2,4},{0,2,4},{0,2,5}}}, }; @@ -88,8 +97,8 @@ graph_t graphs_ico[NUM_ICO_GRAPHS] = { 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,5,9},{1,2,8},{0,5,7},{2,7,8},{2,5,7},{1,4,8},{1,2,10},{5,9,10},{2,5,10},{4,8,11},{7,8,11},{0,7,11},{0,3,9},{0,3,11},{3,4,11},{3,6,9},{3,4,6},{6,9,10},{1,4,6},{1,6,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,5,7},{0,5,9},{2,5,7},{1,4,6},{1,6,10},{5,9,10},{6,9,10},{2,5,10},{1,2,10},{0,7,11},{3,6,9},{0,3,9},{3,4,6},{0,3,11},{3,4,11},{1,2,8},{2,7,8},{1,4,8},{4,8,11},{7,8,11}}}, }; @@ -99,57 +108,57 @@ graph_t graphs_fcc[NUM_FCC_GRAPHS] = { 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{1,2,6},{1,2,5},{1,3,10},{1,3,9},{4,6,10},{4,6,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{4,10,11},{4,5,10},{4,7,9},{3,4,7},{2,9,11},{0,2,11}}}, {1, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{1,2,6},{1,2,5},{1,3,10},{1,3,9},{6,8,10},{4,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{4,10,11},{4,5,10},{4,7,9},{3,4,7},{0,9,11},{0,2,9}}}, {2, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{1,2,6},{1,2,5},{3,9,10},{1,9,10},{6,8,10},{4,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{4,10,11},{4,5,10},{3,7,9},{3,4,9},{2,9,11},{0,2,11}}}, {3, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{2,5,6},{1,5,6},{1,3,10},{1,3,9},{4,6,10},{4,6,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{4,10,11},{4,5,10},{3,7,9},{3,4,9},{0,9,11},{0,2,9}}}, {4, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{2,5,6},{1,5,6},{1,3,10},{1,3,9},{6,8,10},{4,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{5,10,11},{4,5,11},{4,7,9},{3,4,7},{2,9,11},{0,2,11}}}, {5, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{5,7,11},{5,7,9},{2,5,6},{1,5,6},{3,9,10},{1,9,10},{4,6,10},{4,6,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{3,6,8},{3,5,6},{5,10,11},{4,5,11},{3,7,9},{3,4,9},{0,9,11},{0,2,9}}}, {6, 0, -0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{7,9,11},{5,9,11},{1,2,6},{1,2,5},{3,9,10},{1,9,10},{4,6,10},{4,6,8}}}, +5, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{5,6,8},{3,5,8},{4,10,11},{4,5,10},{3,7,9},{3,4,9},{2,9,11},{0,2,11}}}, {7, 0, +0, 1, -5, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{0,4,8},{3,7,9},{2,5,11},{0,7,11},{1,5,9},{2,6,8},{3,4,10},{1,6,10},{3,4,7},{0,4,7},{0,2,11},{0,2,8},{7,9,11},{5,9,11},{2,5,6},{1,5,6},{1,3,10},{1,3,9},{6,8,10},{4,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,2},{3,4,5},{5,6,10},{3,7,8},{1,6,8},{0,10,11},{2,7,9},{4,9,11},{0,6,10},{0,1,6},{1,7,8},{1,2,7},{5,6,8},{3,5,8},{5,10,11},{4,5,11},{4,7,9},{3,4,7},{0,9,11},{0,2,9}}}, }; @@ -159,113 +168,113 @@ graph_t graphs_hcp[NUM_HCP_GRAPHS] = { 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{2,6,7},{2,4,6}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{3,4,7},{0,4,7}}}, {1, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, {2, 0, -0, -1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{2,8,9},{0,2,9},{4,10,11},{0,4,11},{2,6,7},{2,4,6}}}, +6, +2, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{0,9,10},{0,7,10},{3,4,7},{0,4,7}}}, {3, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{2,8,9},{0,2,9},{4,10,11},{0,4,11},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{0,9,10},{0,7,10},{0,3,7},{0,3,4}}}, {4, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{0,8,9},{0,2,8},{0,10,11},{0,4,10},{2,6,7},{2,4,6}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{2,4,8},{1,2,8},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, {5, 0, -0, -1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{0,8,9},{0,2,8},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +8, +10, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{1,9,11},{1,8,9},{2,4,8},{1,2,8},{0,9,10},{0,7,10},{3,4,7},{0,4,7}}}, {6, 0, -6, -2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{0,8,9},{0,2,8},{4,10,11},{0,4,11},{2,6,7},{2,4,6}}}, +0, +1, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, {7, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{3,8,9},{1,3,9},{0,8,9},{0,2,8},{4,10,11},{0,4,11},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{0,9,10},{0,7,10},{0,3,7},{0,3,4}}}, {8, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{2,6,7},{2,4,6}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{6,10,11},{5,6,11},{8,9,11},{1,8,11},{2,4,8},{1,2,8},{0,9,10},{0,7,10},{0,3,7},{0,3,4}}}, {9, 0, -8, -2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +0, +1, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{3,4,7},{0,4,7}}}, {10, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{2,8,9},{0,2,9},{4,10,11},{0,4,11},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{1,9,11},{1,8,9},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, {11, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{0,8,9},{0,2,8},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{3,4,7},{0,4,7}}}, {12, 0, -0, -1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{0,8,9},{0,2,8},{4,10,11},{0,4,11},{2,6,7},{2,4,6}}}, +18, +2, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, {13, 0, -10, -2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{5,6,7},{3,5,7},{3,8,9},{1,3,9},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +0, +1, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{0,9,10},{0,7,10},{0,3,7},{0,3,4}}}, {14, 0, -12, -10, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{1,10,11},{1,5,10},{5,6,7},{3,5,7},{3,8,9},{1,3,9},{0,8,9},{0,2,8},{4,10,11},{0,4,11},{2,6,7},{2,4,6}}}, +20, +2, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{3,5,6},{2,3,5},{5,10,11},{5,6,10},{8,9,11},{1,8,11},{2,4,8},{1,2,8},{7,9,10},{0,7,9},{3,4,7},{0,4,7}}}, {15, 0, 22, 10, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,5},{5,6,10},{0,9,11},{1,9,11},{3,7,8},{2,7,8},{4,6,10},{0,2,4},{5,10,11},{1,5,11},{3,6,7},{3,5,6},{1,8,9},{1,3,8},{2,8,9},{0,2,9},{0,10,11},{0,4,10},{4,6,7},{2,4,7}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,2,5},{1,5,11},{3,6,7},{2,3,4},{9,10,11},{6,7,10},{0,4,8},{0,8,9},{2,5,6},{2,3,6},{5,10,11},{5,6,10},{8,9,11},{1,8,11},{1,4,8},{1,2,4},{7,9,10},{0,7,9},{0,3,7},{0,3,4}}}, }; @@ -275,1527 +284,1527 @@ graph_t graphs_bcc[NUM_BCC_GRAPHS] = { 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {1, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {2, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {3, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {4, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {5, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {6, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {7, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {8, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {9, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {10, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {11, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {12, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {13, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {14, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {15, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {16, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {17, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {18, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {19, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {20, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {21, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {22, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {23, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {24, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {25, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {26, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {27, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {28, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {29, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {30, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {31, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {32, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {33, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {34, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {35, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {36, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {37, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {38, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {39, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {40, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {41, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {42, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {43, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {44, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {45, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {46, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {47, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {48, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {49, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {50, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {51, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {52, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {53, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {54, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {55, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {56, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {57, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {58, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {59, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {60, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {61, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {62, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {63, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {64, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {65, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {66, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {67, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {68, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {69, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {70, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {71, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {72, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {73, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {74, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {75, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {76, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {77, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {78, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {79, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {80, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {81, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {82, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {83, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {84, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {85, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {86, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {87, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {88, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {89, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {90, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {91, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {92, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {93, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {94, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {95, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {96, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {97, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {98, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {99, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {100, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {101, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {102, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {103, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {104, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {105, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {106, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {107, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {108, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {109, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {110, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {111, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {112, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {113, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {114, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {115, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {116, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {117, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {118, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {119, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {120, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {121, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {122, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {123, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {124, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {125, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {126, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {127, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {128, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {129, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {130, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {131, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {132, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {133, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {134, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {135, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {136, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {137, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {138, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {139, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {140, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {141, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {142, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {143, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {144, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {145, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {146, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {147, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {148, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {149, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {150, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {151, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {152, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {153, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {154, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {155, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {156, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {157, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {158, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {159, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {160, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {161, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {162, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {163, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {164, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {165, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{7,11,13},{1,11,13},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{2,8,10},{0,8,10},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {166, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {167, 0, 32, 4, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {168, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {169, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {170, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {171, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {172, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {173, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {174, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {175, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {176, 0, 36, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{5,9,13},{1,9,13},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{4,8,12},{0,8,12},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {177, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {178, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {179, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {180, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{6,9,12},{3,9,12},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{3,9,12},{1,9,12},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {181, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {182, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {183, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {184, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {185, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {186, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {187, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {188, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {189, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {190, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {191, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {192, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {193, 0, 38, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {194, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {195, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {196, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {197, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {198, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {199, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {200, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {201, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {202, 0, 40, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{7,11,13},{6,11,13}}}, {203, 0, 42, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {204, 0, 44, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {205, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{4,11,12},{3,11,12},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{5,9,10},{1,9,10},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {206, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {207, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{6,9,10},{5,9,10},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{4,11,12},{3,11,12},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {208, 0, 46, 3, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {209, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {210, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{7,8,11},{4,8,11},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{5,10,13},{2,10,13},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {211, 0, 49, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{5,10,13},{2,10,13},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{7,8,11},{4,8,11},{6,7,13},{6,7,11}}}, {212, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{4,8,12},{0,8,12},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{6,9,13},{5,9,13},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {213, 0, 51, 2, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{7,8,13},{2,8,13},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{7,8,13},{2,8,13},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {214, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{6,10,12},{0,10,12},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{6,9,11},{3,9,11},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {215, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{2,8,10},{0,8,10}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{7,11,13},{6,11,13}}}, {216, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{3,9,11},{1,9,11},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{1,10,12},{0,10,12},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, {217, 0, 0, 1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{1,3,11},{1,3,9},{3,4,12},{3,4,11},{1,7,13},{1,7,11},{4,7,11},{4,7,8},{1,5,13},{1,5,9},{3,6,12},{3,6,9},{5,6,10},{5,6,9},{0,4,12},{0,4,8},{0,6,12},{0,6,10},{2,7,13},{2,7,8},{2,5,13},{2,5,10},{0,2,10},{0,2,8}}}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,1,12},{0,1,10},{1,5,10},{1,5,9},{0,2,10},{0,2,8},{2,5,13},{2,5,10},{0,4,12},{0,4,8},{1,3,12},{1,3,9},{3,4,12},{3,4,11},{5,6,13},{5,6,9},{3,6,11},{3,6,9},{2,7,13},{2,7,8},{4,7,11},{4,7,8},{6,7,13},{6,7,11}}}, }; @@ -1806,84 +1815,84 @@ graph_t graphs_dcub[NUM_DCUB_GRAPHS] = { 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{5,13,15},{5,6,15},{9,13,14},{8,9,13},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,14},{4,14,15},{5,6,11},{5,11,12},{7,8,11},{7,10,11}}}, {1, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{5,13,15},{5,6,15},{9,13,14},{8,9,13},{12,14,15},{11,12,14}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,14},{4,14,15},{5,6,11},{5,11,12},{7,8,10},{8,10,11}}}, {2, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{5,13,15},{5,6,15},{8,13,14},{8,9,14},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,14},{4,14,15},{5,6,12},{6,11,12},{7,8,11},{7,10,11}}}, {3, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{5,13,15},{5,6,15},{8,13,14},{8,9,14},{12,14,15},{11,12,14}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,14},{4,14,15},{5,6,12},{6,11,12},{7,8,10},{8,10,11}}}, {4, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{6,13,15},{5,6,13},{9,13,14},{8,9,13},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,15},{5,14,15},{5,6,11},{5,11,12},{7,8,11},{7,10,11}}}, {5, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{6,13,15},{5,6,13},{8,13,14},{8,9,14},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,15},{5,14,15},{5,6,12},{6,11,12},{7,8,11},{7,10,11}}}, {6, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{6,13,15},{5,6,13},{8,13,14},{8,9,14},{12,14,15},{11,12,14}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,13},{12,13,14},{4,5,14},{4,14,15},{5,6,11},{5,11,12},{7,8,11},{7,10,11}}}, {7, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{9,10,11},{7,9,10},{5,13,15},{5,6,15},{8,13,14},{8,9,14},{12,14,15},{11,12,14}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,13},{12,13,14},{4,5,14},{4,14,15},{5,6,11},{5,11,12},{7,8,10},{8,10,11}}}, {8, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{9,10,11},{7,9,10},{6,13,15},{5,6,13},{9,13,14},{8,9,13},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,13},{12,13,14},{4,5,14},{4,14,15},{5,6,12},{6,11,12},{7,8,11},{7,10,11}}}, {9, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{6,10,12},{4,6,10},{9,10,11},{7,9,10},{6,13,15},{5,6,13},{8,13,14},{8,9,14},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,8},{4,8,9},{10,12,13},{12,13,14},{4,5,15},{5,14,15},{5,6,12},{6,11,12},{7,8,10},{8,10,11}}}, {10, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{5,7,8},{4,5,7},{4,10,12},{4,6,12},{9,10,11},{7,9,10},{6,13,15},{5,6,13},{8,13,14},{8,9,14},{11,14,15},{11,12,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,15},{7,13,15},{4,6,9},{6,8,9},{10,12,13},{12,13,14},{4,5,14},{4,14,15},{5,6,11},{5,11,12},{7,8,10},{8,10,11}}}, {11, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{4,7,10},{0,5,6},{0,4,5},{0,4,6},{2,11,12},{2,10,12},{2,10,11},{1,7,8},{1,8,9},{1,7,9},{6,12,15},{5,8,13},{3,13,15},{3,13,14},{9,11,14},{3,14,15},{4,7,8},{4,5,8},{6,10,12},{4,6,10},{7,10,11},{7,9,11},{5,13,15},{5,6,15},{9,13,14},{8,9,13},{12,14,15},{11,12,14}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,9,15},{5,12,14},{6,8,11},{1,7,8},{1,8,9},{1,7,9},{7,10,13},{2,10,11},{2,11,12},{2,10,12},{3,13,14},{3,14,15},{3,13,15},{7,9,13},{9,13,15},{4,6,8},{4,8,9},{10,12,14},{10,13,14},{4,5,15},{5,14,15},{5,6,12},{6,11,12},{7,8,11},{7,10,11}}}, }; @@ -1894,168 +1903,168 @@ graph_t graphs_dhex[NUM_DHEX_GRAPHS] = { 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{6,11,14},{5,6,11},{4,8,15},{4,6,15},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {1, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{6,11,14},{5,6,11},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {2, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,15},{11,14,15},{5,6,11},{5,10,11}}}, {3, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,15},{11,14,15},{5,6,10},{6,10,11}}}, {4, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {5, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {6, 0, -0, -1, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, - -{7, -0, 53, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,15},{11,14,15},{5,6,10},{6,10,11}}}, + +{7, +0, +0, +1, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,9},{5,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {8, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,9},{5,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {9, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {10, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {11, 0, -0, -1, +55, +4, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,13},{4,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,15},{11,14,15},{5,6,10},{6,10,11}}}, {12, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {13, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {14, 0, -55, -4, +0, +1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{7,13,15},{7,8,15}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {15, 0, -59, -2, +0, +1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{11,13,14},{10,11,13},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {16, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,9},{5,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {17, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,9},{5,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {18, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {19, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{9,10,12},{7,9,10},{4,9,12},{4,5,12},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,14},{7,13,14},{4,9,15},{9,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {20, 0, -61, +59, 4, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{7,10,12},{7,9,12},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{4,8,15},{4,6,15},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,13},{12,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,11},{5,10,11}}}, {21, 0, -0, -1, +63, +2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{7,10,12},{7,9,12},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{6,11,14},{5,6,11},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,13},{12,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,10},{7,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {22, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{7,10,12},{7,9,12},{5,9,12},{4,5,9},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,13},{12,13,14},{4,9,15},{9,13,15},{4,5,8},{4,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, {23, 0, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{{7,10,13},{5,11,12},{6,14,15},{0,4,5},{0,5,6},{0,4,6},{4,8,9},{2,10,12},{2,10,11},{2,11,12},{3,13,14},{3,13,15},{3,14,15},{1,7,9},{1,7,8},{1,8,9},{7,10,12},{7,9,12},{4,9,12},{4,5,12},{10,13,14},{10,11,14},{5,11,14},{5,6,14},{6,8,15},{4,6,8},{8,13,15},{7,8,13}}}, +{{0,4,5},{0,5,6},{0,4,6},{4,6,15},{5,8,10},{1,7,8},{1,8,9},{1,7,9},{7,9,13},{2,10,11},{2,11,12},{2,10,12},{11,12,14},{3,13,14},{3,14,15},{3,13,15},{7,12,13},{12,13,14},{4,9,15},{9,13,15},{4,5,9},{5,8,9},{7,8,12},{8,10,12},{6,11,14},{6,14,15},{5,6,10},{6,10,11}}}, }; diff --git a/src/USER-PTM/ptm_graph_data.h b/src/USER-PTM/ptm_graph_data.h index 251c82d2f5..882cb0e213 100644 --- a/src/USER-PTM/ptm_graph_data.h +++ b/src/USER-PTM/ptm_graph_data.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_GRAPH_DATA_H #define PTM_GRAPH_DATA_H diff --git a/src/USER-PTM/ptm_graph_tools.cpp b/src/USER-PTM/ptm_graph_tools.cpp index 7f9dcaa6c7..403c0f8099 100644 --- a/src/USER-PTM/ptm_graph_tools.cpp +++ b/src/USER-PTM/ptm_graph_tools.cpp @@ -1,4 +1,13 @@ -#include +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include #include #include "ptm_graph_tools.h" #include "ptm_constants.h" diff --git a/src/USER-PTM/ptm_graph_tools.h b/src/USER-PTM/ptm_graph_tools.h index 7befad526b..3bd6b72fbb 100644 --- a/src/USER-PTM/ptm_graph_tools.h +++ b/src/USER-PTM/ptm_graph_tools.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_GRAPH_TOOLS_H #define PTM_GRAPH_TOOLS_H diff --git a/src/USER-PTM/ptm_index.cpp b/src/USER-PTM/ptm_index.cpp index 28cbcbd6f5..5ac1f3916c 100644 --- a/src/USER-PTM/ptm_index.cpp +++ b/src/USER-PTM/ptm_index.cpp @@ -1,125 +1,180 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ptm_convex_hull_incremental.h" -#include "ptm_graph_data.h" -#include "ptm_deformation_gradient.h" +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include "ptm_alloy_types.h" +#include "ptm_constants.h" +#include "ptm_convex_hull_incremental.h" +#include "ptm_deformation_gradient.h" +#include "ptm_functions.h" +#include "ptm_graph_data.h" +#include "ptm_initialize_data.h" #include "ptm_neighbour_ordering.h" #include "ptm_normalize_vertices.h" -#include "ptm_quat.h" #include "ptm_polar.h" -#include "ptm_initialize_data.h" +#include "ptm_quat.h" #include "ptm_structure_matcher.h" -#include "ptm_functions.h" -#include "ptm_constants.h" +#include +#include +#include +#include +#include +#include +#include +static double calculate_interatomic_distance(int type, double scale) { + assert(type >= 1 && type <= 8); -//todo: verify that c == norm(template[1]) -static double calculate_interatomic_distance(int type, double scale) -{ - assert(type >= 1 && type <= 7); - double c[8] = {0, 1, 1, (7. - 3.5 * sqrt(3)), 1, 1, sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3))}; + // these values should be equal to norm(template[1]) + double c[9] = {0, + 1, + 1, + (7. - 3.5 * sqrt(3)), + 1, + 1, + sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), + sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), + -3. / 11 + 6 * sqrt(3) / 11}; return c[type] / scale; } -static double calculate_lattice_constant(int type, double interatomic_distance) -{ - assert(type >= 1 && type <= 7); - double c[8] = {0, 2 / sqrt(2), 2 / sqrt(2), 2. / sqrt(3), 2 / sqrt(2), 1, 4 / sqrt(3), 4 / sqrt(3)}; +static double calculate_lattice_constant(int type, + double interatomic_distance) { + assert(type >= 1 && type <= 8); + double c[9] = {0, 2 / sqrt(2), 2 / sqrt(2), 2. / sqrt(3), 2 / sqrt(2), + 1, 4 / sqrt(3), 4 / sqrt(3), sqrt(3)}; return c[type] * interatomic_distance; } -static int rotate_into_fundamental_zone(int type, double* q) -{ - if (type == PTM_MATCH_SC) return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_FCC) return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_BCC) return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_ICO) return ptm::rotate_quaternion_into_icosahedral_fundamental_zone(q); - if (type == PTM_MATCH_HCP) return ptm::rotate_quaternion_into_hcp_fundamental_zone(q); - if (type == PTM_MATCH_DCUB) return ptm::rotate_quaternion_into_diamond_cubic_fundamental_zone(q); - if (type == PTM_MATCH_DHEX) return ptm::rotate_quaternion_into_diamond_hexagonal_fundamental_zone(q); +static int rotate_into_fundamental_zone(int type, + bool output_conventional_orientation, + double *q) { + if (type == PTM_MATCH_SC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_FCC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_BCC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_ICO) + return ptm::rotate_quaternion_into_icosahedral_fundamental_zone(q); + + if (type == PTM_MATCH_HCP || type == PTM_MATCH_GRAPHENE) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_hcp_fundamental_zone(q); + } + } + + if (type == PTM_MATCH_DCUB) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_diamond_cubic_fundamental_zone(q); + } + } + + if (type == PTM_MATCH_DHEX) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_diamond_hexagonal_fundamental_zone(q); + } + } + return -1; } -static void order_points(ptm_local_handle_t local_handle, int num_points, double (*unpermuted_points)[3], int32_t* unpermuted_numbers, bool topological_ordering, - int8_t* ordering, double (*points)[3], int32_t* numbers) -{ - if (topological_ordering) - { - double normalized_points[PTM_MAX_INPUT_POINTS][3]; - ptm::normalize_vertices(num_points, unpermuted_points, normalized_points); - int ret = ptm::calculate_neighbour_ordering((void*)local_handle, num_points, (const double (*)[3])normalized_points, ordering); - if (ret != 0) - topological_ordering = false; - } - - if (!topological_ordering) - for (int i=0;iref_struct; +static void output_data(ptm::result_t *res, double (*points)[3], + int32_t *numbers, size_t *ordering, + bool output_conventional_orientation, int32_t *p_type, + int32_t *p_alloy_type, double *p_scale, double *p_rmsd, + double *q, double *F, double *F_res, double *U, + double *P, double *p_interatomic_distance, + double *p_lattice_constant, size_t *output_indices) { + const ptm::refdata_t *ref = res->ref_struct; if (ref == NULL) return; *p_type = ref->type; - if (p_alloy_type != NULL && unpermuted_numbers != NULL) + if (p_alloy_type != NULL) *p_alloy_type = ptm::find_alloy_type(ref, res->mapping, numbers); - int bi = rotate_into_fundamental_zone(ref->type, res->q); int8_t temp[PTM_MAX_POINTS]; - for (int i=0;inum_nbrs+1;i++) - temp[ref->mapping[bi][i]] = res->mapping[i]; - - memcpy(res->mapping, temp, (ref->num_nbrs+1) * sizeof(int8_t)); - - if (F != NULL && F_res != NULL) + memset(temp, -1, PTM_MAX_POINTS * sizeof(int8_t)); + int bi = rotate_into_fundamental_zone(ref->type, + output_conventional_orientation, res->q); + //todo: return if bi == -1 + if (bi != -1) { + if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) + { + for (int i = 0; i < ref->num_nbrs + 1; i++) + temp[ref->mapping_conventional[bi][i]] = res->mapping[i]; + } + else + { + for (int i = 0; i < ref->num_nbrs + 1; i++) + temp[ref->mapping[bi][i]] = res->mapping[i]; + } + } + + memcpy(res->mapping, temp, (ref->num_nbrs + 1) * sizeof(int8_t)); + + if (F != NULL && F_res != NULL) { double scaled_points[PTM_MAX_INPUT_POINTS][3]; ptm::subtract_barycentre(ref->num_nbrs + 1, points, scaled_points); - for (int i = 0;inum_nbrs + 1;i++) - { + for (int i = 0; i < ref->num_nbrs + 1; i++) { scaled_points[i][0] *= res->scale; scaled_points[i][1] *= res->scale; scaled_points[i][2] *= res->scale; } - ptm::calculate_deformation_gradient(ref->num_nbrs + 1, ref->points, res->mapping, scaled_points, ref->penrose, F, F_res); + + const double (*ref_template)[3] = ref->points; + const double (*ref_penrose)[3] = ref->penrose; + if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) + { + if (ref->template_indices[bi] == 1) + { + ref_template = ref->points_alt1; + ref_penrose = ref->penrose_alt1; + } + else if (ref->template_indices[bi] == 2) + { + ref_template = ref->points_alt2; + ref_penrose = ref->penrose_alt2; + } + else if (ref->template_indices[bi] == 3) + { + ref_template = ref->points_alt3; + ref_penrose = ref->penrose_alt3; + } + } + + ptm::calculate_deformation_gradient(ref->num_nbrs + 1, ref_template, + res->mapping, scaled_points, ref_penrose, + F, F_res); + if (ref->type == PTM_MATCH_GRAPHENE) // hack for pseudo-2d structures + F[8] = 1; if (P != NULL && U != NULL) ptm::polar_decomposition_3x3(F, false, U, P); } - if (mapping != NULL) - for (int i=0;inum_nbrs + 1;i++) - mapping[i] = ordering[res->mapping[i]]; + if (output_indices != NULL) + for (int i = 0; i < ref->num_nbrs + 1; i++) + output_indices[i] = ordering[res->mapping[i]]; - double interatomic_distance = calculate_interatomic_distance(ref->type, res->scale); - double lattice_constant = calculate_lattice_constant(ref->type, interatomic_distance); + double interatomic_distance = + calculate_interatomic_distance(ref->type, res->scale); + double lattice_constant = + calculate_lattice_constant(ref->type, interatomic_distance); if (p_interatomic_distance != NULL) *p_interatomic_distance = interatomic_distance; @@ -132,67 +187,73 @@ static void output_data(ptm::result_t* res, int num_points, int32_t* unpermuted_ memcpy(q, res->q, 4 * sizeof(double)); } - extern bool ptm_initialized; -int ptm_index( ptm_local_handle_t local_handle, int32_t flags, - int num_points, double (*unpermuted_points)[3], int32_t* unpermuted_numbers, bool topological_ordering, - int32_t* p_type, int32_t* p_alloy_type, double* p_scale, double* p_rmsd, double* q, double* F, double* F_res, - double* U, double* P, int8_t* mapping, double* p_interatomic_distance, double* p_lattice_constant) -{ +int ptm_index(ptm_local_handle_t local_handle, size_t atom_index, + int(get_neighbours)(void *vdata, size_t central_index, size_t atom_index, int num, + size_t *nbr_indices, int32_t *numbers, + double (*nbr_pos)[3]), + void *nbrlist, int32_t flags, + bool output_conventional_orientation, int32_t *p_type, + int32_t *p_alloy_type, double *p_scale, double *p_rmsd, double *q, + double *F, double *F_res, double *U, double *P, + double *p_interatomic_distance, double *p_lattice_constant, + size_t *output_indices) { assert(ptm_initialized); - assert(num_points <= PTM_MAX_INPUT_POINTS); - - if (flags & PTM_CHECK_SC) - assert(num_points >= PTM_NUM_POINTS_SC); - - if (flags & PTM_CHECK_BCC) - assert(num_points >= PTM_NUM_POINTS_BCC); - - if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) - assert(num_points >= PTM_NUM_POINTS_FCC); - - if (flags & (PTM_CHECK_DCUB | PTM_CHECK_DHEX)) - assert(num_points >= PTM_NUM_POINTS_DCUB); int ret = 0; ptm::result_t res; res.ref_struct = NULL; res.rmsd = INFINITY; - int8_t ordering[PTM_MAX_INPUT_POINTS]; - double points[PTM_MAX_POINTS][3]; - int32_t numbers[PTM_MAX_POINTS]; + size_t ordering[PTM_MAX_INPUT_POINTS]; + int32_t numbers[PTM_MAX_INPUT_POINTS]; + double points[PTM_MAX_INPUT_POINTS][3]; - int8_t dordering[PTM_MAX_INPUT_POINTS]; - double dpoints[PTM_MAX_POINTS][3]; - int32_t dnumbers[PTM_MAX_POINTS]; + size_t dordering[PTM_MAX_INPUT_POINTS]; + int32_t dnumbers[PTM_MAX_INPUT_POINTS]; + double dpoints[PTM_MAX_INPUT_POINTS][3]; + + size_t gordering[PTM_MAX_INPUT_POINTS]; + int32_t gnumbers[PTM_MAX_INPUT_POINTS]; + double gpoints[PTM_MAX_INPUT_POINTS][3]; ptm::convexhull_t ch; double ch_points[PTM_MAX_INPUT_POINTS][3]; + int num_lpoints = 0; - if (flags & (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC)) - { - int num_lpoints = std::min(std::min(PTM_MAX_POINTS, 20), num_points); - order_points(local_handle, num_lpoints, unpermuted_points, unpermuted_numbers, topological_ordering, ordering, points, numbers); - ptm::normalize_vertices(num_lpoints, points, ch_points); - ch.ok = false; - - if (flags & PTM_CHECK_SC) - ret = match_general(&ptm::structure_sc, ch_points, points, &ch, &res); - + if (flags & (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | + PTM_CHECK_BCC)) { + int min_points = PTM_NUM_POINTS_SC; if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) - ret = match_fcc_hcp_ico(ch_points, points, flags, &ch, &res); - + min_points = PTM_NUM_POINTS_FCC; if (flags & PTM_CHECK_BCC) - ret = match_general(&ptm::structure_bcc, ch_points, points, &ch, &res); + min_points = PTM_NUM_POINTS_BCC; + + num_lpoints = ptm::calculate_neighbour_ordering( + local_handle, atom_index, min_points, get_neighbours, nbrlist, false, + ordering, points, numbers); + if (num_lpoints >= min_points) { + ptm::normalize_vertices(num_lpoints, points, ch_points); + ch.ok = false; + + if (flags & PTM_CHECK_SC) + ret = match_general(&ptm::structure_sc, ch_points, points, &ch, &res); + + if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) + ret = match_fcc_hcp_ico(ch_points, points, flags, &ch, &res); + + if (flags & PTM_CHECK_BCC) + ret = match_general(&ptm::structure_bcc, ch_points, points, &ch, &res); + } } - if (flags & (PTM_CHECK_DCUB | PTM_CHECK_DHEX)) - { - ret = ptm::calculate_diamond_neighbour_ordering(num_points, unpermuted_points, unpermuted_numbers, dordering, dpoints, dnumbers); - if (ret == 0) - { + if (flags & (PTM_CHECK_DCUB | PTM_CHECK_DHEX)) { + const int num_inner = 4, num_outer = 3, max_snbrs = 12; + ret = ptm::calculate_two_shell_neighbour_ordering( + (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, + num_outer, max_snbrs, false, dordering, dpoints, dnumbers); + if (ret == 0) { ptm::normalize_vertices(PTM_NUM_NBRS_DCUB + 1, dpoints, ch_points); ch.ok = false; @@ -200,19 +261,42 @@ int ptm_index( ptm_local_handle_t local_handle, int32_t flags, } } - if (res.ref_struct != NULL && (res.ref_struct->type == PTM_MATCH_DCUB || res.ref_struct->type == PTM_MATCH_DHEX)) - { - output_data( &res, num_points, unpermuted_numbers, dpoints, dnumbers, dordering, - p_type, p_alloy_type, p_scale, p_rmsd, q, F, F_res, - U, P, mapping, p_interatomic_distance, p_lattice_constant); + if (flags & PTM_CHECK_GRAPHENE) { + const int num_inner = 3, num_outer = 2, max_snbrs = 12; + ret = ptm::calculate_two_shell_neighbour_ordering( + (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, + num_outer, max_snbrs, true, gordering, gpoints, gnumbers); + if (ret == 0) { + ret = match_graphene(gpoints, &res); + } } - else - { - output_data( &res, num_points, unpermuted_numbers, points, numbers, ordering, - p_type, p_alloy_type, p_scale, p_rmsd, q, F, F_res, - U, P, mapping, p_interatomic_distance, p_lattice_constant); + + *p_type = PTM_MATCH_NONE; + if (p_alloy_type != NULL) + *p_alloy_type = PTM_ALLOY_NONE; + + if (output_indices != NULL) + memset(output_indices, -1, PTM_MAX_INPUT_POINTS * sizeof(size_t)); + + if (res.ref_struct == NULL) + return PTM_NO_ERROR; + + if (res.ref_struct->type == PTM_MATCH_DCUB || + res.ref_struct->type == PTM_MATCH_DHEX) { + output_data(&res, dpoints, dnumbers, dordering, + output_conventional_orientation, p_type, p_alloy_type, p_scale, + p_rmsd, q, F, F_res, U, P, p_interatomic_distance, + p_lattice_constant, output_indices); + } else if (res.ref_struct->type == PTM_MATCH_GRAPHENE) { + output_data(&res, gpoints, gnumbers, gordering, + output_conventional_orientation, p_type, p_alloy_type, p_scale, + p_rmsd, q, F, F_res, U, P, p_interatomic_distance, + p_lattice_constant, output_indices); + } else { + output_data(&res, points, numbers, ordering, output_conventional_orientation, + p_type, p_alloy_type, p_scale, p_rmsd, q, F, F_res, U, P, + p_interatomic_distance, p_lattice_constant, output_indices); } return PTM_NO_ERROR; } - diff --git a/src/USER-PTM/ptm_initialize_data.cpp b/src/USER-PTM/ptm_initialize_data.cpp index 3a0ed5e466..73a0f16d72 100644 --- a/src/USER-PTM/ptm_initialize_data.cpp +++ b/src/USER-PTM/ptm_initialize_data.cpp @@ -1,6 +1,15 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include #include -#include +#include #include #include #include diff --git a/src/USER-PTM/ptm_initialize_data.h b/src/USER-PTM/ptm_initialize_data.h index 5374fbf7d0..47b7aa4f20 100644 --- a/src/USER-PTM/ptm_initialize_data.h +++ b/src/USER-PTM/ptm_initialize_data.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_INITIALIZE_DATA_H #define PTM_INITIALIZE_DATA_H @@ -9,6 +18,7 @@ #include "ptm_neighbour_ordering.h" #include "ptm_canonical_coloured.h" #include "ptm_convex_hull_incremental.h" +#include "ptm_alt_templates.h" namespace ptm { @@ -20,23 +30,181 @@ typedef struct int num_facets; int max_degree; int num_graphs; - int num_mappings; graph_t* graphs; const double (*points)[3]; + const double (*points_alt1)[3]; + const double (*points_alt2)[3]; + const double (*points_alt3)[3]; const double (*penrose)[3]; + const double (*penrose_alt1)[3]; + const double (*penrose_alt2)[3]; + const double (*penrose_alt3)[3]; + int num_mappings; const int8_t (*mapping)[PTM_MAX_POINTS]; + const int8_t (*mapping_conventional)[PTM_MAX_POINTS]; + const int8_t *template_indices; } refdata_t; -//refdata_t structure_sc = { .type = PTM_MATCH_SC, .num_nbrs = 6, .num_facets = 8, .max_degree = 4, .num_graphs = NUM_SC_GRAPHS, .graphs = graphs_sc, .points = ptm_template_sc, .penrose = penrose_sc , .mapping = mapping_sc }; -const refdata_t structure_sc = { PTM_MATCH_SC, 6, 8, 4, NUM_SC_GRAPHS, NUM_CUBIC_MAPPINGS, graphs_sc, ptm_template_sc, penrose_sc, mapping_sc }; -const refdata_t structure_fcc = { PTM_MATCH_FCC, 12, 20, 6, NUM_FCC_GRAPHS, NUM_CUBIC_MAPPINGS, graphs_fcc, ptm_template_fcc, penrose_fcc, mapping_fcc }; -const refdata_t structure_hcp = { PTM_MATCH_HCP, 12, 20, 6, NUM_HCP_GRAPHS, NUM_HEX_MAPPINGS, graphs_hcp, ptm_template_hcp, penrose_hcp, mapping_hcp }; -const refdata_t structure_ico = { PTM_MATCH_ICO, 12, 20, 6, NUM_ICO_GRAPHS, NUM_ICO_MAPPINGS, graphs_ico, ptm_template_ico, penrose_ico, mapping_ico }; -const refdata_t structure_bcc = { PTM_MATCH_BCC, 14, 24, 8, NUM_BCC_GRAPHS, NUM_CUBIC_MAPPINGS, graphs_bcc, ptm_template_bcc, penrose_bcc, mapping_bcc }; -const refdata_t structure_dcub = { PTM_MATCH_DCUB, 16, 28, 8, NUM_DCUB_GRAPHS, NUM_DCUB_MAPPINGS, graphs_dcub, ptm_template_dcub, penrose_dcub, mapping_dcub }; -const refdata_t structure_dhex = { PTM_MATCH_DHEX, 16, 28, 8, NUM_DHEX_GRAPHS, NUM_DHEX_MAPPINGS, graphs_dhex, ptm_template_dhex, penrose_dhex, mapping_dhex }; +const refdata_t structure_sc = { PTM_MATCH_SC, //.type + 6, //.num_nbrs + 8, //.num_facets + 4, //.max_degree + NUM_SC_GRAPHS, //.num_graphs + graphs_sc, //.graphs + ptm_template_sc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_sc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_sc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; +const refdata_t structure_fcc = { PTM_MATCH_FCC, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_FCC_GRAPHS, //.num_graphs + graphs_fcc, //.graphs + ptm_template_fcc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_fcc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_fcc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; + +const refdata_t structure_hcp = { PTM_MATCH_HCP, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_HCP_GRAPHS, //.num_graphs + graphs_hcp, //.graphs + ptm_template_hcp, //.points + ptm_template_hcp_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_hcp, //.penrose + penrose_hcp_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_HEX_MAPPINGS, //.num_mappings + mapping_hcp, //.mapping + mapping_hcp_conventional, //.mapping_conventional + template_indices_hcp, //.template_indices + }; + +const refdata_t structure_ico = { PTM_MATCH_ICO, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_ICO_GRAPHS, //.num_graphs + graphs_ico, //.graphs + ptm_template_ico, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_ico, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_ICO_MAPPINGS, //.num_mappings + mapping_ico, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; + +const refdata_t structure_bcc = { PTM_MATCH_BCC, //.type + 14, //.num_nbrs + 24, //.num_facets + 8, //.max_degree + NUM_BCC_GRAPHS, //.num_graphs + graphs_bcc, //.graphs + ptm_template_bcc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_bcc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_bcc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; + +const refdata_t structure_dcub = { PTM_MATCH_DCUB, //.type + 16, //.num_nbrs + 28, //.num_facets + 8, //.max_degree + NUM_DCUB_GRAPHS, //.num_graphs + graphs_dcub, //.graphs + ptm_template_dcub, //.points + ptm_template_dcub_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_dcub, //.penrose + penrose_dcub_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_DCUB_MAPPINGS, //.num_mappings + mapping_dcub, //.mapping + mapping_dcub_conventional, //.mapping_conventional + template_indices_dcub, //.template_indices + }; + +const refdata_t structure_dhex = { PTM_MATCH_DHEX, //.type + 16, //.num_nbrs + 28, //.num_facets + 8, //.max_degree + NUM_DHEX_GRAPHS, //.num_graphs + graphs_dhex, //.graphs + ptm_template_dhex, //.points + ptm_template_dhex_alt1, //.points_alt1 + ptm_template_dhex_alt2, //.points_alt2 + ptm_template_dhex_alt3, //.points_alt3 + penrose_dhex, //.penrose + penrose_dhex_alt1, //.penrose_alt1 + penrose_dhex_alt2, //.penrose_alt2 + penrose_dhex_alt3, //.penrose_alt3 + NUM_DHEX_MAPPINGS, //.num_mappings + mapping_dhex, //.mapping + mapping_dhex_conventional, //.mapping_conventional + template_indices_dhex, //.template_indices + }; + +const refdata_t structure_graphene = { PTM_MATCH_GRAPHENE, //.type + 9, //.num_nbrs + -1, //.num_facets + -1, //.max_degree + -1, //.num_graphs + NULL, //.graphs + ptm_template_graphene, //.points + ptm_template_graphene_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_graphene, //.penrose + penrose_graphene_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + -1, //.num_mappings + mapping_graphene, //.mapping + mapping_graphene_conventional, //.mapping_conventional + template_indices_graphene, //.template_indices + }; } #ifdef __cplusplus diff --git a/src/USER-PTM/ptm_neighbour_ordering.cpp b/src/USER-PTM/ptm_neighbour_ordering.cpp index d5948b9dc6..621ef2565f 100644 --- a/src/USER-PTM/ptm_neighbour_ordering.cpp +++ b/src/USER-PTM/ptm_neighbour_ordering.cpp @@ -1,11 +1,24 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +//todo: normalize vertices + #include #include #include #include #include +#include #include "ptm_constants.h" #include "ptm_voronoi_cell.h" #include "ptm_neighbour_ordering.h" +#include "ptm_normalize_vertices.h" namespace ptm { @@ -15,8 +28,20 @@ typedef struct double area; double dist; int index; + int inner; + int32_t number; + double offset[3]; } sorthelper_t; +typedef struct +{ + size_t index; + int32_t number; + double area; + double offset[3]; + +} solidnbr_t; + static bool sorthelper_compare(sorthelper_t const& a, sorthelper_t const& b) { if (a.area > b.area) @@ -31,10 +56,37 @@ static bool sorthelper_compare(sorthelper_t const& a, sorthelper_t const& b) return false; } -//todo: change voronoi code to return errors rather than exiting -static int calculate_voronoi_face_areas(int num_points, const double (*_points)[3], double* normsq, double max_norm, ptm_voro::voronoicell_neighbor* v, std::vector& nbr_indices, std::vector& face_areas) +static double dot_product(double* a, double* b) { - const double k = 1000 * max_norm; //todo: reduce this constant + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +static void cross_product(double* a, double* b, double* c) +{ + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; +} + +static double calculate_solid_angle(double* R1, double* R2, double* R3) //norms of R1-R3 must be 1 +{ + double R2R3[3]; + cross_product(R2, R3, R2R3); + double numerator = dot_product(R1, R2R3); + + double r1r2 = dot_product(R1, R2); + double r2r3 = dot_product(R2, R3); + double r3r1 = dot_product(R3, R1); + + double denominator = 1 + r1r2 + r3r1 + r2r3; + return fabs(2 * atan2(numerator, denominator)); +} + +//todo: change voronoi code to return errors rather than exiting +static int calculate_voronoi_face_areas(int num_points, const double (*_points)[3], double* normsq, double max_norm, ptm_voro::voronoicell_neighbor* v, bool calc_solid_angles, + std::vector& nbr_indices, std::vector& face_areas) +{ + const double k = 10 * max_norm; v->init(-k,k,-k,k,-k,k); for (int i=1;ineighbors(nbr_indices); - v->face_areas(face_areas); - return 0; + +//v->face_areas(face_areas); + if (!calc_solid_angles) + { + v->face_areas(face_areas); + return 0; + } + else + { + std::vector face_vertices; + std::vector vertices; + + v->face_vertices(face_vertices); + v->vertices(0, 0, 0, vertices); + + size_t num_vertices = vertices.size() / 3; + for (size_t i=0;inumber_of_faces(); + +#ifdef DEBUG + printf("number of voronoi faces: %d\n", num_faces); +#endif + +//std::vector solids(face_areas.size()+1); + + size_t c = 0; + for (int current_face=0;current_face 0) + { + double solid_angle = 0; + int u = face_vertices[c]; + int v = face_vertices[c+1]; + for (int i=2;i nbr_indices(num_points + 6); std::vector face_areas(num_points + 6); - int ret = calculate_voronoi_face_areas(num_points, points, normsq, max_norm, voronoi_handle, nbr_indices, face_areas); + int ret = calculate_voronoi_face_areas(num_points, points, normsq, max_norm, voronoi_handle, calc_solid_angles, nbr_indices, face_areas); if (ret != 0) return ret; @@ -93,24 +216,61 @@ int calculate_neighbour_ordering(void* _voronoi_handle, int num_points, const do areas[index] = face_areas[i]; } - sorthelper_t data[PTM_MAX_INPUT_POINTS]; for (int i=0;i claimed; + claimed.insert(atom_index); + for (int i=0;i= 3) + int inner = data[i].inner; + int nbr_atom_index = data[i].index; + + bool already_claimed = claimed.find(nbr_atom_index) != claimed.end(); + if (counts[inner] >= num_outer || already_claimed) continue; - ordering[1 + 4 + 3 * p + counts[p]] = q; - counts[p]++; - index++; + nbr_indices[1 + num_inner + num_outer * inner + counts[inner]] = nbr_atom_index; + numbers[1 + num_inner + num_outer * inner + counts[inner]] = data[i].number; + memcpy(points[1 + num_inner + num_outer * inner + counts[inner]], &data[i].offset, 3 * sizeof(double)); + claimed.insert(nbr_atom_index); + + counts[inner]++; num_found++; - if (num_found >= 12) + if (num_found >= num_inner * num_outer) break; } - if (num_found != 12) + if (num_found != num_inner * num_outer) return -1; - for (int i=0;i +#include namespace ptm { -int calculate_neighbour_ordering(void* voronoi_handle, int num_points, const double (*_points)[3], int8_t* ordering); +int calculate_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int min_points, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, + double (*nbr_pos)[3]), void* nbrlist, bool calc_solid_angles, + size_t* nbr_indices, double (*points)[3], int32_t* numbers); -int calculate_diamond_neighbour_ordering( int num_points, double (*unpermuted_points)[3], int32_t* unpermuted_numbers, - int8_t* ordering, double (*points)[3], int32_t* numbers); +int calculate_two_shell_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, double (*nbr_pos)[3]), void* nbrlist, + int num_inner, int num_outer, int max_snbrs, bool calc_solid_angles, + size_t* nbr_indices, double (*points)[3], int32_t* numbers); void* voronoi_initialize_local(); void voronoi_uninitialize_local(void* ptr); diff --git a/src/USER-PTM/ptm_normalize_vertices.cpp b/src/USER-PTM/ptm_normalize_vertices.cpp index 22e3c1e670..3d35fbce43 100644 --- a/src/USER-PTM/ptm_normalize_vertices.cpp +++ b/src/USER-PTM/ptm_normalize_vertices.cpp @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include namespace ptm { diff --git a/src/USER-PTM/ptm_normalize_vertices.h b/src/USER-PTM/ptm_normalize_vertices.h index dc93db94a3..558cd62008 100644 --- a/src/USER-PTM/ptm_normalize_vertices.h +++ b/src/USER-PTM/ptm_normalize_vertices.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_NORMALIZE_VERTICES_H #define PTM_NORMALIZE_VERTICES_H diff --git a/src/USER-PTM/ptm_polar.cpp b/src/USER-PTM/ptm_polar.cpp index d5dca957be..fa199ca656 100644 --- a/src/USER-PTM/ptm_polar.cpp +++ b/src/USER-PTM/ptm_polar.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * -/_|:|_|_\- + * -/_|:|_|_\- * * This code is a modification of D.L. Theobald's QCP rotation code. * It has been adapted to calculate the polar decomposition of a 3x3 matrix @@ -14,7 +14,7 @@ * USA * * dtheobald@brandeis.edu - * + * * Pu Liu * Johnson & Johnson Pharmaceutical Research and Development, L.L.C. * 665 Stockton Drive @@ -22,7 +22,7 @@ * USA * * pliu24@its.jnj.com - * + * * * If you use this QCP rotation calculation method in a publication, please * reference: @@ -33,7 +33,7 @@ * Acta Crystallographica A 61(4):478-480. * * Pu Liu, Dmitris K. Agrafiotis, and Douglas L. Theobald (2009) - * "Fast determination of the optimal rotational matrix for macromolecular + * "Fast determination of the optimal rotational matrix for macromolecular * superpositions." * Journal of Computational Chemistry 31(7):1561-1563. * @@ -63,7 +63,7 @@ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Source: started anew. * @@ -82,14 +82,13 @@ * * 2016/05/29 QCP method adapted for polar decomposition of a 3x3 matrix, * for use in Polyhedral Template Matching. - * + * ******************************************************************************/ #include #include -#include +#include #include "ptm_quat.h" -#include "ptm_polar.h" namespace ptm { @@ -327,7 +326,7 @@ void InnerProduct(double *A, int num, const double (*coords1)[3], double (*coord A[6] += z1 * x2; A[7] += z1 * y2; - A[8] += z1 * z2; + A[8] += z1 * z2; } } diff --git a/src/USER-PTM/ptm_polar.h b/src/USER-PTM/ptm_polar.h index e1980f974a..e03963048b 100644 --- a/src/USER-PTM/ptm_polar.h +++ b/src/USER-PTM/ptm_polar.h @@ -1,9 +1,17 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_POLAR_H #define PTM_POLAR_H #include #include -#include namespace ptm { diff --git a/src/USER-PTM/ptm_quat.cpp b/src/USER-PTM/ptm_quat.cpp index 0d1787984e..f5764f6bb9 100644 --- a/src/USER-PTM/ptm_quat.cpp +++ b/src/USER-PTM/ptm_quat.cpp @@ -1,138 +1,159 @@ -#include +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include #include #include +#include namespace ptm { #define SIGN(x) (x >= 0 ? 1 : -1) -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -#define SQRT_2 1.4142135623730951454746218587388284504414 -#define HALF_SQRT_2 0.7071067811865474617150084668537601828575 +const double generator_cubic[24][4] = { + { 1, 0, 0, 0 }, + { sqrt(2)/2, sqrt(2)/2, 0, 0 }, + { sqrt(2)/2, 0, sqrt(2)/2, 0 }, + { sqrt(2)/2, 0, 0, sqrt(2)/2 }, + { sqrt(2)/2, 0, 0, -sqrt(2)/2 }, + { sqrt(2)/2, 0, -sqrt(2)/2, 0 }, + { sqrt(2)/2, -sqrt(2)/2, -0, -0 }, + { 0.5, 0.5, 0.5, 0.5 }, + { 0.5, 0.5, 0.5, -0.5 }, + { 0.5, 0.5, -0.5, 0.5 }, + { 0.5, 0.5, -0.5, -0.5 }, + { 0.5, -0.5, 0.5, 0.5 }, + { 0.5, -0.5, 0.5, -0.5 }, + { 0.5, -0.5, -0.5, 0.5 }, + { 0.5, -0.5, -0.5, -0.5 }, + { 0, 1, 0, 0 }, + { 0, sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, 0, sqrt(2)/2 }, + { 0, sqrt(2)/2, 0, -sqrt(2)/2 }, + { 0, sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, sqrt(2)/2, sqrt(2)/2 }, + { 0, 0, sqrt(2)/2, -sqrt(2)/2 }, + { 0, 0, 0, 1 }, +}; -#define PHI 1.6180339887498949025257388711906969547272 -#define HALF_PHI 0.8090169943749474512628694355953484773636 +const double generator_diamond_cubic[12][4] = { + { 1, 0, 0, 0 }, + { 0.5, 0.5, 0.5, 0.5 }, + { 0.5, 0.5, 0.5, -0.5 }, + { 0.5, 0.5, -0.5, 0.5 }, + { 0.5, 0.5, -0.5, -0.5 }, + { 0.5, -0.5, 0.5, 0.5 }, + { 0.5, -0.5, 0.5, -0.5 }, + { 0.5, -0.5, -0.5, 0.5 }, + { 0.5, -0.5, -0.5, -0.5 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, +}; -#define INV_PHI 0.6180339887498947915034364086750429123640 -#define HALF_INV_PHI 0.3090169943749473957517182043375214561820 - -#define SQRT_5_ 2.23606797749978969640917366873127623544061835961152572427089 -#define SQRT_2_3 0.8164965809277260344600790631375275552273 -#define SQRT_1_6 0.4082482904638630172300395315687637776136 +const double generator_hcp[6][4] = { + { 1, 0, 0, 0 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, + { 0, sqrt(3)/2, 0.5, 0 }, + { 0, sqrt(3)/2, -0.5, 0 }, + { 0, 0, 1, 0 }, +}; -double generator_cubic[24][4] = { {1, 0, 0, 0 }, - {0, 1, 0, 0 }, - {0, 0, 1, 0 }, - {0, 0, 0, 1 }, - {0.5, 0.5, 0.5, 0.5 }, - {0.5, 0.5, -0.5, 0.5 }, - {0.5, -0.5, 0.5, 0.5 }, - {0.5, -0.5, -0.5, 0.5 }, - {-0.5, 0.5, 0.5, 0.5 }, - {-0.5, 0.5, -0.5, 0.5 }, - {-0.5, -0.5, 0.5, 0.5 }, - {-0.5, -0.5, -0.5, 0.5 }, - {HALF_SQRT_2, HALF_SQRT_2, 0, 0 }, - {HALF_SQRT_2, 0, HALF_SQRT_2, 0 }, - {HALF_SQRT_2, 0, 0, HALF_SQRT_2 }, - {-HALF_SQRT_2, HALF_SQRT_2, 0, 0 }, - {-HALF_SQRT_2, 0, HALF_SQRT_2, 0 }, - {-HALF_SQRT_2, 0, 0, HALF_SQRT_2 }, - {0, HALF_SQRT_2, HALF_SQRT_2, 0 }, - {0, HALF_SQRT_2, 0, HALF_SQRT_2 }, - {0, 0, HALF_SQRT_2, HALF_SQRT_2 }, - {0, -HALF_SQRT_2, HALF_SQRT_2, 0 }, - {0, -HALF_SQRT_2, 0, HALF_SQRT_2 }, - {0, 0, -HALF_SQRT_2, HALF_SQRT_2 } }; +const double generator_hcp_conventional[12][4] = { + { 1, 0, 0, 0 }, + { sqrt(3)/2, 0, 0, 0.5 }, + { sqrt(3)/2, 0, 0, -0.5 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, + { 0, 1, 0, 0 }, + { 0, sqrt(3)/2, 0.5, 0 }, + { 0, sqrt(3)/2, -0.5, 0 }, + { 0, 0.5, sqrt(3)/2, 0 }, + { 0, 0.5, -sqrt(3)/2, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, +}; -double generator_diamond_cubic[12][4] = { {1, 0, 0, 0 }, - {0, 1, 0, 0 }, - {0, 0, 1, 0 }, - {0, 0, 0, 1 }, - {0.5, 0.5, 0.5, 0.5 }, - {0.5, 0.5, -0.5, 0.5 }, - {0.5, -0.5, 0.5, 0.5 }, - {0.5, -0.5, -0.5, 0.5 }, - {-0.5, 0.5, 0.5, 0.5 }, - {-0.5, 0.5, -0.5, 0.5 }, - {-0.5, -0.5, 0.5, 0.5 }, - {-0.5, -0.5, -0.5, 0.5 } }; +const double generator_diamond_hexagonal[3][4] = { + { 1, 0, 0, 0 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, +}; -double generator_hcp[6][4] = { {1, 0, 0, 0}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, -0.5, -0.5, -0.5}, - {0, SQRT_2_3, -SQRT_1_6, -SQRT_1_6}, - {0, SQRT_1_6, -SQRT_2_3, SQRT_1_6}, - {0, SQRT_1_6, SQRT_1_6, -SQRT_2_3} }; +const double generator_icosahedral[60][4] = { + { 1, 0, 0, 0 }, + { (1+sqrt(5))/4, 0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0, sqrt(50-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0, 0, sqrt(5./8-sqrt(5)/8) }, + { (1+sqrt(5))/4, 0, 0, -sqrt(5./8-sqrt(5)/8) }, + { (1+sqrt(5))/4, 0, -sqrt(50-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { 0.5, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, + { 0.5, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, sqrt((5+sqrt(5))/10), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0, sqrt(50-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, -sqrt(50-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, -sqrt((5+sqrt(5))/10), sqrt(25-10*sqrt(5))/10 }, + { 0.5, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, + { 0.5, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, + { 0.5, -0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, + { 0.5, -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, + { 1/(1+sqrt(5)), (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0, sqrt((5+sqrt(5))/10), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0, 0, sqrt(1-1/(2*sqrt(5)+6)) }, + { 1/(1+sqrt(5)), 0, 0, -sqrt(1-1/(2*sqrt(5)+6)) }, + { 1/(1+sqrt(5)), 0, -sqrt((5+sqrt(5))/10), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, + { 0, 1, 0, 0 }, + { 0, (1+sqrt(5))/4, sqrt(5./8-sqrt(5)/8), 0 }, + { 0, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(50-10*sqrt(5))/10 }, + { 0, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(50-10*sqrt(5))/10 }, + { 0, (1+sqrt(5))/4, -sqrt(5./8-sqrt(5)/8), 0 }, + { 0, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(50-10*sqrt(5))/10 }, + { 0, 0.5, sqrt(25-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, + { 0, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt((5+sqrt(5))/10) }, + { 0, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(50-10*sqrt(5))/10 }, + { 0, 1/(1+sqrt(5)), sqrt(1-1/(2*sqrt(5)+6)), 0 }, + { 0, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt((5+sqrt(5))/10) }, + { 0, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt((5+sqrt(5))/10) }, + { 0, 1/(1+sqrt(5)), -sqrt(1-1/(2*sqrt(5)+6)), 0 }, + { 0, 0, sqrt((5+sqrt(5))/10), -sqrt(50-10*sqrt(5))/10 }, + { 0, 0, sqrt(50-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, +}; -double generator_diamond_hexagonal[3][4] = { {1, 0, 0, 0}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, -0.5, -0.5, -0.5} }; - -double generator_icosahedral[60][4] = { {1, 0, 0, 0}, - {HALF_PHI, -HALF_INV_PHI, -0.5, 0}, - {HALF_PHI, 0, -HALF_INV_PHI, -0.5}, - {HALF_PHI, -0.5, 0, -HALF_INV_PHI}, - {HALF_PHI, HALF_INV_PHI, -0.5, 0}, - {HALF_PHI, 0, HALF_INV_PHI, -0.5}, - {HALF_PHI, -0.5, 0, HALF_INV_PHI}, - {HALF_PHI, 0.5, 0, -HALF_INV_PHI}, - {HALF_PHI, 0, -HALF_INV_PHI, 0.5}, - {HALF_PHI, -HALF_INV_PHI, 0.5, 0}, - {HALF_PHI, 0, HALF_INV_PHI, 0.5}, - {HALF_PHI, HALF_INV_PHI, 0.5, 0}, - {HALF_PHI, 0.5, 0, HALF_INV_PHI}, - {0.5, HALF_PHI, -HALF_INV_PHI, 0}, - {0.5, HALF_PHI, HALF_INV_PHI, 0}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, -0.5}, - {0.5, 0.5, -0.5, 0.5}, - {0.5, 0.5, -0.5, -0.5}, - {0.5, HALF_INV_PHI, 0, HALF_PHI}, - {0.5, HALF_INV_PHI, 0, -HALF_PHI}, - {0.5, 0, HALF_PHI, -HALF_INV_PHI}, - {0.5, 0, HALF_PHI, HALF_INV_PHI}, - {0.5, 0, -HALF_PHI, -HALF_INV_PHI}, - {0.5, 0, -HALF_PHI, HALF_INV_PHI}, - {0.5, -HALF_INV_PHI, 0, HALF_PHI}, - {0.5, -HALF_INV_PHI, 0, -HALF_PHI}, - {0.5, -0.5, 0.5, 0.5}, - {0.5, -0.5, 0.5, -0.5}, - {0.5, -0.5, -0.5, 0.5}, - {0.5, -0.5, -0.5, -0.5}, - {0.5, -HALF_PHI, -HALF_INV_PHI, 0}, - {0.5, -HALF_PHI, HALF_INV_PHI, 0}, - {HALF_INV_PHI, -HALF_PHI, 0, -0.5}, - {HALF_INV_PHI, 0, -0.5, -HALF_PHI}, - {HALF_INV_PHI, -0.5, -HALF_PHI, 0}, - {HALF_INV_PHI, 0, 0.5, -HALF_PHI}, - {HALF_INV_PHI, -HALF_PHI, 0, 0.5}, - {HALF_INV_PHI, 0.5, -HALF_PHI, 0}, - {HALF_INV_PHI, HALF_PHI, 0, -0.5}, - {HALF_INV_PHI, -0.5, HALF_PHI, 0}, - {HALF_INV_PHI, 0, -0.5, HALF_PHI}, - {HALF_INV_PHI, HALF_PHI, 0, 0.5}, - {HALF_INV_PHI, 0, 0.5, HALF_PHI}, - {HALF_INV_PHI, 0.5, HALF_PHI, 0}, - {0, 1, 0, 0}, - {0, HALF_PHI, -0.5, HALF_INV_PHI}, - {0, HALF_PHI, -0.5, -HALF_INV_PHI}, - {0, HALF_PHI, 0.5, HALF_INV_PHI}, - {0, HALF_PHI, 0.5, -HALF_INV_PHI}, - {0, 0.5, HALF_INV_PHI, -HALF_PHI}, - {0, 0.5, HALF_INV_PHI, HALF_PHI}, - {0, 0.5, -HALF_INV_PHI, -HALF_PHI}, - {0, 0.5, -HALF_INV_PHI, HALF_PHI}, - {0, HALF_INV_PHI, -HALF_PHI, 0.5}, - {0, HALF_INV_PHI, -HALF_PHI, -0.5}, - {0, HALF_INV_PHI, HALF_PHI, 0.5}, - {0, HALF_INV_PHI, HALF_PHI, -0.5}, - {0, 0, 1, 0}, - {0, 0, 0, 1} }; static void quat_rot(double* r, double* a, double* b) { @@ -142,13 +163,13 @@ static void quat_rot(double* r, double* a, double* b) b[3] = (r[0] * a[3] + r[1] * a[2] - r[2] * a[1] + r[3] * a[0]); } -static int rotate_quaternion_into_fundamental_zone(int num_generators, double (*generator)[4], double* q) +static int rotate_quaternion_into_fundamental_zone(int num_generators, const double (*generator)[4], double* q) { double max = 0.0; int i = 0, bi = -1; for (i=0;i max) { @@ -158,7 +179,7 @@ static int rotate_quaternion_into_fundamental_zone(int num_generators, double (* } double f[4]; - quat_rot(q, generator[bi], f); + quat_rot(q, (double*)generator[bi], f); memcpy(q, &f, 4 * sizeof(double)); if (q[0] < 0) { @@ -191,6 +212,11 @@ int rotate_quaternion_into_hcp_fundamental_zone(double* q) return rotate_quaternion_into_fundamental_zone(6, generator_hcp, q); } +int rotate_quaternion_into_hcp_conventional_fundamental_zone(double* q) +{ + return rotate_quaternion_into_fundamental_zone(12, generator_hcp_conventional, q); +} + int rotate_quaternion_into_diamond_hexagonal_fundamental_zone(double* q) { return rotate_quaternion_into_fundamental_zone(3, generator_diamond_hexagonal, q); @@ -219,6 +245,26 @@ void normalize_quaternion(double* q) q[3] /= size; } +void quaternion_to_rotation_matrix(double* q, double* u) +{ + double a = q[0]; + double b = q[1]; + double c = q[2]; + double d = q[3]; + + u[0] = a*a + b*b - c*c - d*d; + u[1] = 2*b*c - 2*a*d; + u[2] = 2*b*d + 2*a*c; + + u[3] = 2*b*c + 2*a*d; + u[4] = a*a - b*b + c*c - d*d; + u[5] = 2*c*d - 2*a*b; + + u[6] = 2*b*d - 2*a*c; + u[7] = 2*c*d + 2*a*b; + u[8] = a*a - b*b - c*c + d*d; +} + void rotation_matrix_to_quaternion(double* u, double* q) { double r11 = u[0]; @@ -236,14 +282,14 @@ void rotation_matrix_to_quaternion(double* u, double* q) q[2] = (1.0 - r11 + r22 - r33) / 4.0; q[3] = (1.0 - r11 - r22 + r33) / 4.0; - q[0] = sqrt(MAX(0, q[0])); - q[1] = sqrt(MAX(0, q[1])); - q[2] = sqrt(MAX(0, q[2])); - q[3] = sqrt(MAX(0, q[3])); + q[0] = sqrt(std::max(0., q[0])); + q[1] = sqrt(std::max(0., q[1])); + q[2] = sqrt(std::max(0., q[2])); + q[3] = sqrt(std::max(0., q[3])); - double m0 = MAX(q[0], q[1]); - double m1 = MAX(q[2], q[3]); - double max = MAX(m0, m1); + double m0 = std::max(q[0], q[1]); + double m1 = std::max(q[2], q[3]); + double max = std::max(m0, m1); int i = 0; for (i=0;i<4;i++) @@ -278,30 +324,10 @@ void rotation_matrix_to_quaternion(double* u, double* q) normalize_quaternion(q); } -void quaternion_to_rotation_matrix(double* q, double* u) -{ - double a = q[0]; - double b = q[1]; - double c = q[2]; - double d = q[3]; - - u[0] = a*a + b*b - c*c - d*d; - u[1] = 2*b*c - 2*a*d; - u[2] = 2*b*d + 2*a*c; - - u[3] = 2*b*c + 2*a*d; - u[4] = a*a - b*b + c*c - d*d; - u[5] = 2*c*d - 2*a*b; - - u[6] = 2*b*d - 2*a*c; - u[7] = 2*c*d + 2*a*b; - u[8] = a*a - b*b - c*c + d*d; -} - double quat_quick_misorientation(double* q1, double* q2) { double t = quat_dot(q1, q2); - t = MIN(1, MAX(-1, t)); + t = std::min(1., std::max(-1., t)); return 2 * t * t - 1; } @@ -310,91 +336,5 @@ double quat_misorientation(double* q1, double* q2) return acos(quat_quick_misorientation(q1, q2)); } - -double quat_quick_disorientation_cubic(double* q0, double* q1) -{ - double qrot[4]; - double qinv[4] = {q0[0], -q0[1], -q0[2], -q0[3]}; - quat_rot(qinv, q1, qrot); - - rotate_quaternion_into_cubic_fundamental_zone(qrot); - double t = qrot[0]; - t = MIN(1, MAX(-1, t)); - return 2 * t * t - 1; -} - -double quat_disorientation_cubic(double* q0, double* q1) -{ - return acos(quat_quick_disorientation_cubic(q0, q1)); -} - -double quat_quick_disorientation_diamond_cubic(double* q0, double* q1) -{ - double qrot[4]; - double qinv[4] = {q0[0], -q0[1], -q0[2], -q0[3]}; - quat_rot(qinv, q1, qrot); - - rotate_quaternion_into_diamond_cubic_fundamental_zone(qrot); - double t = qrot[0]; - t = MIN(1, MAX(-1, t)); - return 2 * t * t - 1; -} - -double quat_disorientation_diamond_cubic(double* q0, double* q1) -{ - return acos(quat_quick_disorientation_diamond_cubic(q0, q1)); -} - -double quat_quick_disorientation_hcp(double* q0, double* q1) -{ - double qrot[4]; - double qinv[4] = {q0[0], -q0[1], -q0[2], -q0[3]}; - quat_rot(qinv, q1, qrot); - - rotate_quaternion_into_hcp_fundamental_zone(qrot); - double t = qrot[0]; - t = MIN(1, MAX(-1, t)); - return 2 * t * t - 1; -} - -double quat_disorientation_hcp(double* q0, double* q1) -{ - return acos(quat_quick_disorientation_hcp(q0, q1)); -} - -double quat_quick_disorientation_diamond_hexagonal(double* q0, double* q1) -{ - double qrot[4]; - double qinv[4] = {q0[0], -q0[1], -q0[2], -q0[3]}; - quat_rot(qinv, q1, qrot); - - rotate_quaternion_into_diamond_hexagonal_fundamental_zone(qrot); - double t = qrot[0]; - t = MIN(1, MAX(-1, t)); - return 2 * t * t - 1; -} - -double quat_disorientation_diamond_hexagonal(double* q0, double* q1) -{ - return acos(quat_quick_disorientation_diamond_hexagonal(q0, q1)); -} - -double quat_quick_disorientation_icosahedral(double* q0, double* q1) -{ - double qrot[4]; - double qinv[4] = {q0[0], -q0[1], -q0[2], -q0[3]}; - quat_rot(qinv, q1, qrot); - - rotate_quaternion_into_icosahedral_fundamental_zone(qrot); - double t = qrot[0]; - t = MIN(1, MAX(-1, t)); - return 2 * t * t - 1; -} - -double quat_disorientation_icosahedral(double* q0, double* q1) -{ - return acos(quat_quick_disorientation_icosahedral(q0, q1)); -} - } diff --git a/src/USER-PTM/ptm_quat.h b/src/USER-PTM/ptm_quat.h index 74caa2c62c..6f4d88920e 100644 --- a/src/USER-PTM/ptm_quat.h +++ b/src/USER-PTM/ptm_quat.h @@ -1,3 +1,12 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #ifndef PTM_QUAT_H #define PTM_QUAT_H @@ -7,26 +16,15 @@ int rotate_quaternion_into_cubic_fundamental_zone(double* q); int rotate_quaternion_into_diamond_cubic_fundamental_zone(double* q); int rotate_quaternion_into_icosahedral_fundamental_zone(double* q); int rotate_quaternion_into_hcp_fundamental_zone(double* q); +int rotate_quaternion_into_hcp_conventional_fundamental_zone(double* q); int rotate_quaternion_into_diamond_hexagonal_fundamental_zone(double* q); void normalize_quaternion(double* q); void quaternion_to_rotation_matrix(double* q, double* U); void rotation_matrix_to_quaternion(double* u, double* q); double quat_dot(double* a, double* b); -double quat_quick_misorientation(double* q1, double* q2); double quat_misorientation(double* q1, double* q2); -double quat_quick_disorientation_cubic(double* q0, double* q1); -double quat_disorientation_cubic(double* q0, double* q1); -double quat_quick_disorientation_diamond_cubic(double* q0, double* q1); -double quat_disorientation_diamond_cubic(double* q0, double* q1); -double quat_quick_disorientation_hcp(double* q0, double* q1); -double quat_disorientation_hcp(double* q0, double* q1); -double quat_quick_disorientation_diamond_hexagonal(double* q0, double* q1); -double quat_disorientation_diamond_hexagonal(double* q0, double* q1); -double quat_quick_disorientation_icosahedral(double* q0, double* q1); -double quat_disorientation_icosahedral(double* q0, double* q1); - } #endif diff --git a/src/USER-PTM/ptm_structure_matcher.cpp b/src/USER-PTM/ptm_structure_matcher.cpp index 169a2d0256..7eb4cd3d84 100644 --- a/src/USER-PTM/ptm_structure_matcher.cpp +++ b/src/USER-PTM/ptm_structure_matcher.cpp @@ -1,6 +1,15 @@ +/*Copyright (c) 2016 PM Larsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include #include -#include +#include #include #include #include @@ -294,5 +303,74 @@ int match_dcub_dhex(double (*ch_points)[3], double (*points)[3], int32_t flags, return PTM_NO_ERROR; } + +static void check_graphs_graphene( const refdata_t* s, + int num_points, + const double (*ideal_points)[3], + double (*normalized)[3], + int8_t* mapping, + result_t* res) +{ + double G1 = 0, G2 = 0; + for (int i=0;irmsd) + { + res->rmsd = rmsd; + res->scale = scale; + res->ref_struct = s; + memcpy(res->q, q, 4 * sizeof(double)); + memcpy(res->mapping, mapping, sizeof(int8_t) * num_points); + } +} + +int match_graphene(double (*points)[3], result_t* res) +{ + int num_nbrs = structure_graphene.num_nbrs; + int num_points = num_nbrs + 1; + const double (*ideal_points)[3] = structure_graphene.points; + + double normalized[PTM_MAX_POINTS][3]; + subtract_barycentre(num_points, points, normalized); + + int8_t mapping[PTM_MAX_POINTS]; + for (int i=0;i inline void voronoicell_base::add_to_stack(vc_class &vc,int lp,int *&stackp2) { +(void)vc; for(int *k(ds2);k &v) { reset_edges(); } +/** Returns the number of faces of a computed Voronoi cell. + * \return The number of faces. */ +int voronoicell_base::number_of_faces() { + int i,j,k,l,m,s=0; + for(i=1;i=0) { + s++; + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + do { + m=ed[k][l]; + ed[k][l]=-1-m; + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); + + } + } + reset_edges(); + return s; +} + +/** Returns a vector of the vertex vectors in the global coordinate system. + * \param[out] v the vector to store the results in. + * \param[in] (x,y,z) the position vector of the particle in the global + * coordinate system. */ +void voronoicell_base::vertices(double x,double y,double z,std::vector &v) { + v.resize(3*p); + double *ptsp=pts; + for(int i=0;i<3*p;i+=3) { + v[i]=x+*(ptsp++)*0.5; + v[i+1]=y+*(ptsp++)*0.5; + v[i+2]=z+*(ptsp++)*0.5; + } +} + +/** For each face, this routine outputs a bracketed sequence of numbers + * containing a list of all the vertices that make up that face. + * \param[out] v the vector to store the results in. */ +void voronoicell_base::face_vertices(std::vector &v) { + int i,j,k,l,m,vp(0),vn; + v.clear(); + for(i=1;i=0) { + v.push_back(0); + v.push_back(i); + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + do { + v.push_back(k); + m=ed[k][l]; + ed[k][l]=-1-m; + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); + vn=v.size(); + v[vp]=vn-vp-1; + vp=vn; + } + } + reset_edges(); +} + // Explicit instantiation template bool voronoicell_base::nplane(voronoicell_neighbor&,double,double,double,double,int); template void voronoicell_base::check_memory_for_copy(voronoicell_neighbor&,voronoicell_base*); diff --git a/src/USER-PTM/ptm_voronoi_cell.h b/src/USER-PTM/ptm_voronoi_cell.h index e0284bc56f..007e36f8b7 100644 --- a/src/USER-PTM/ptm_voronoi_cell.h +++ b/src/USER-PTM/ptm_voronoi_cell.h @@ -1,3 +1,46 @@ +/* +Voro++ Copyright (c) 2008, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from the U.S. Dept. of Energy). All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +(1) Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +(2) Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +(3) Neither the name of the University of California, Lawrence Berkeley +National Laboratory, U.S. Dept. of Energy nor the names of its contributors may +be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You are under no obligation whatsoever to provide any bug fixes, patches, or +upgrades to the features, functionality or performance of the source code +("Enhancements") to anyone; however, if you choose to make your Enhancements +available either publicly, or directly to Lawrence Berkeley National +Laboratory, without imposing a separate written license agreement for such +Enhancements, then you hereby grant the following license: a non-exclusive, +royalty-free perpetual license to install, use, modify, prepare derivative +works, incorporate into other computer software, distribute, and sublicense +such enhancements or derivative works thereof, in binary and source code form. +*/ + + // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) diff --git a/src/USER-PTM/ptm_voronoi_config.h b/src/USER-PTM/ptm_voronoi_config.h index 46c5a4b915..d0718a3630 100644 --- a/src/USER-PTM/ptm_voronoi_config.h +++ b/src/USER-PTM/ptm_voronoi_config.h @@ -1,3 +1,46 @@ +/* +Voro++ Copyright (c) 2008, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from the U.S. Dept. of Energy). All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +(1) Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +(2) Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +(3) Neither the name of the University of California, Lawrence Berkeley +National Laboratory, U.S. Dept. of Energy nor the names of its contributors may +be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You are under no obligation whatsoever to provide any bug fixes, patches, or +upgrades to the features, functionality or performance of the source code +("Enhancements") to anyone; however, if you choose to make your Enhancements +available either publicly, or directly to Lawrence Berkeley National +Laboratory, without imposing a separate written license agreement for such +Enhancements, then you hereby grant the following license: a non-exclusive, +royalty-free perpetual license to install, use, modify, prepare derivative +works, incorporate into other computer software, distribute, and sublicense +such enhancements or derivative works thereof, in binary and source code form. +*/ + + // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) From 8a28046b4c5662db1aa0c196e14f86b4e2e64278 Mon Sep 17 00:00:00 2001 From: pmla Date: Fri, 15 Feb 2019 18:52:40 -0500 Subject: [PATCH 2/9] typo in PTM docs --- doc/src/compute_ptm_atom.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/compute_ptm_atom.txt b/doc/src/compute_ptm_atom.txt index 86aea9aeba..02b3badfbd 100644 --- a/doc/src/compute_ptm_atom.txt +++ b/doc/src/compute_ptm_atom.txt @@ -93,7 +93,7 @@ interatomic distance qw qx qy -qw :ul +qz :ul The type is a number from 0 to 8. The rmsd is a positive real number. The interatomic distance is computed from the scale factor in the RMSD equation. From bae2e61fa03a2a2d1c2232d98328b0106d1a2d0b Mon Sep 17 00:00:00 2001 From: pmla Date: Fri, 15 Feb 2019 19:40:37 -0500 Subject: [PATCH 3/9] documentation bugfix --- doc/src/compute_ptm_atom.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/compute_ptm_atom.txt b/doc/src/compute_ptm_atom.txt index 02b3badfbd..dfe3afe970 100644 --- a/doc/src/compute_ptm_atom.txt +++ b/doc/src/compute_ptm_atom.txt @@ -95,7 +95,7 @@ qx qy qz :ul -The type is a number from 0 to 8. The rmsd is a positive real number. +The type is a number from -1 to 8. The rmsd is a positive real number. The interatomic distance is computed from the scale factor in the RMSD equation. The (qw,qx,qy,qz) parameters represent the orientation of the local structure in quaternion form. The reference coordinates for each template (from which the From 551e7a5943e4ae479b1825b4061d277f45d63a0f Mon Sep 17 00:00:00 2001 From: pmla Date: Fri, 15 Feb 2019 19:42:28 -0500 Subject: [PATCH 4/9] added contact address --- src/USER-PTM/README | 1 + 1 file changed, 1 insertion(+) diff --git a/src/USER-PTM/README b/src/USER-PTM/README index 42b8738f86..d661fa5ac5 100644 --- a/src/USER-PTM/README +++ b/src/USER-PTM/README @@ -24,3 +24,4 @@ Preprint available at: http://arxiv.org/abs/1603.05143 +Contact email: pmla@mit.edu From 6724ebbdc1da7c84cae271ccc68e27d42468bbc4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 16 Feb 2019 13:31:38 -0500 Subject: [PATCH 5/9] remove trailing whitespace --- src/USER-PTM/ptm_polar.cpp | 14 +++++++------- src/USER-PTM/ptm_structure_matcher.cpp | 2 +- src/USER-PTM/ptm_voronoi_cell.cpp | 10 +++++----- src/USER-PTM/ptm_voronoi_cell.h | 10 +++++----- src/USER-PTM/ptm_voronoi_config.h | 10 +++++----- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/USER-PTM/ptm_polar.cpp b/src/USER-PTM/ptm_polar.cpp index fa199ca656..6996d8dfef 100644 --- a/src/USER-PTM/ptm_polar.cpp +++ b/src/USER-PTM/ptm_polar.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * -/_|:|_|_\- + * -/_|:|_|_\- * * This code is a modification of D.L. Theobald's QCP rotation code. * It has been adapted to calculate the polar decomposition of a 3x3 matrix @@ -14,7 +14,7 @@ * USA * * dtheobald@brandeis.edu - * + * * Pu Liu * Johnson & Johnson Pharmaceutical Research and Development, L.L.C. * 665 Stockton Drive @@ -22,7 +22,7 @@ * USA * * pliu24@its.jnj.com - * + * * * If you use this QCP rotation calculation method in a publication, please * reference: @@ -33,7 +33,7 @@ * Acta Crystallographica A 61(4):478-480. * * Pu Liu, Dmitris K. Agrafiotis, and Douglas L. Theobald (2009) - * "Fast determination of the optimal rotational matrix for macromolecular + * "Fast determination of the optimal rotational matrix for macromolecular * superpositions." * Journal of Computational Chemistry 31(7):1561-1563. * @@ -63,7 +63,7 @@ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Source: started anew. * @@ -82,7 +82,7 @@ * * 2016/05/29 QCP method adapted for polar decomposition of a 3x3 matrix, * for use in Polyhedral Template Matching. - * + * ******************************************************************************/ #include @@ -326,7 +326,7 @@ void InnerProduct(double *A, int num, const double (*coords1)[3], double (*coord A[6] += z1 * x2; A[7] += z1 * y2; - A[8] += z1 * z2; + A[8] += z1 * z2; } } diff --git a/src/USER-PTM/ptm_structure_matcher.cpp b/src/USER-PTM/ptm_structure_matcher.cpp index 7eb4cd3d84..055a2bf3b0 100644 --- a/src/USER-PTM/ptm_structure_matcher.cpp +++ b/src/USER-PTM/ptm_structure_matcher.cpp @@ -308,7 +308,7 @@ static void check_graphs_graphene( const refdata_t* s, int num_points, const double (*ideal_points)[3], double (*normalized)[3], - int8_t* mapping, + int8_t* mapping, result_t* res) { double G1 = 0, G2 = 0; diff --git a/src/USER-PTM/ptm_voronoi_cell.cpp b/src/USER-PTM/ptm_voronoi_cell.cpp index 87db58fe30..65ad8b3324 100644 --- a/src/USER-PTM/ptm_voronoi_cell.cpp +++ b/src/USER-PTM/ptm_voronoi_cell.cpp @@ -4,19 +4,19 @@ Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. +list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. +and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -27,7 +27,7 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code diff --git a/src/USER-PTM/ptm_voronoi_cell.h b/src/USER-PTM/ptm_voronoi_cell.h index 007e36f8b7..8137aa3340 100644 --- a/src/USER-PTM/ptm_voronoi_cell.h +++ b/src/USER-PTM/ptm_voronoi_cell.h @@ -4,19 +4,19 @@ Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. +list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. +and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -27,7 +27,7 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code diff --git a/src/USER-PTM/ptm_voronoi_config.h b/src/USER-PTM/ptm_voronoi_config.h index d0718a3630..ca5dcd9559 100644 --- a/src/USER-PTM/ptm_voronoi_config.h +++ b/src/USER-PTM/ptm_voronoi_config.h @@ -4,19 +4,19 @@ Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. +list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. +and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -27,7 +27,7 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code From 9168df575abf63926b662f23b4e45b8177410ffa Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 16 Feb 2019 13:40:34 -0500 Subject: [PATCH 6/9] replace (evil) tabs with blanks --- src/USER-PTM/compute_ptm_atom.cpp | 4 +- src/USER-PTM/ptm_alloy_types.cpp | 130 +- src/USER-PTM/ptm_alt_templates.h | 182 +- src/USER-PTM/ptm_canonical_coloured.cpp | 244 +- src/USER-PTM/ptm_constants.h | 274 +-- src/USER-PTM/ptm_convex_hull_incremental.cpp | 504 ++-- src/USER-PTM/ptm_convex_hull_incremental.h | 16 +- src/USER-PTM/ptm_deformation_gradient.cpp | 52 +- src/USER-PTM/ptm_deformation_gradient.h | 392 ++-- src/USER-PTM/ptm_functions.h | 10 +- src/USER-PTM/ptm_fundamental_mappings.h | 442 ++-- src/USER-PTM/ptm_graph_data.cpp | 130 +- src/USER-PTM/ptm_graph_data.h | 12 +- src/USER-PTM/ptm_graph_tools.cpp | 60 +- src/USER-PTM/ptm_index.cpp | 406 ++-- src/USER-PTM/ptm_initialize_data.cpp | 66 +- src/USER-PTM/ptm_initialize_data.h | 340 +-- src/USER-PTM/ptm_neighbour_ordering.cpp | 506 ++-- src/USER-PTM/ptm_neighbour_ordering.h | 12 +- src/USER-PTM/ptm_normalize_vertices.cpp | 76 +- src/USER-PTM/ptm_polar.cpp | 450 ++-- src/USER-PTM/ptm_quat.cpp | 452 ++-- src/USER-PTM/ptm_structure_matcher.cpp | 524 ++--- src/USER-PTM/ptm_structure_matcher.h | 10 +- src/USER-PTM/ptm_voronoi_cell.cpp | 2162 +++++++++--------- src/USER-PTM/ptm_voronoi_cell.h | 544 ++--- 26 files changed, 4000 insertions(+), 4000 deletions(-) diff --git a/src/USER-PTM/compute_ptm_atom.cpp b/src/USER-PTM/compute_ptm_atom.cpp index cdfd933936..270f6f0079 100644 --- a/src/USER-PTM/compute_ptm_atom.cpp +++ b/src/USER-PTM/compute_ptm_atom.cpp @@ -3,9 +3,9 @@ http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov - Copyright (2003) Sandia Corporation. Under the terms of Contract + Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed + certain rights in this software. This software is distributed under the GNU General Public License. diff --git a/src/USER-PTM/ptm_alloy_types.cpp b/src/USER-PTM/ptm_alloy_types.cpp index 40e8211386..b6b94a3733 100644 --- a/src/USER-PTM/ptm_alloy_types.cpp +++ b/src/USER-PTM/ptm_alloy_types.cpp @@ -15,107 +15,107 @@ namespace ptm { #define NUM_ALLOY_TYPES 3 static uint32_t typedata[NUM_ALLOY_TYPES][3] = { - {PTM_MATCH_FCC, PTM_ALLOY_L10, 0x00000db6}, - {PTM_MATCH_FCC, PTM_ALLOY_L12_CU, 0x00000492}, - {PTM_MATCH_FCC, PTM_ALLOY_L12_AU, 0x00001ffe}, + {PTM_MATCH_FCC, PTM_ALLOY_L10, 0x00000db6}, + {PTM_MATCH_FCC, PTM_ALLOY_L12_CU, 0x00000492}, + {PTM_MATCH_FCC, PTM_ALLOY_L12_AU, 0x00001ffe}, }; static bool test_pure(int num_nbrs, int32_t* numbers) { - for (int i=1;inum_nbrs+1;i++) - binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1; + int8_t binary[PTM_MAX_POINTS]; + for (int i=0;inum_nbrs+1;i++) + binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1; - for (int i=1;inum_nbrs+1;i++) - if (binary[i] != binary[0]) - return false; + for (int i=num_inner+1;inum_nbrs+1;i++) + if (binary[i] != binary[0]) + return false; - return true; + return true; } static int32_t canonical_alloy_representation(const refdata_t* ref, int8_t* mapping, int32_t* numbers) { - int8_t binary[PTM_MAX_POINTS]; - for (int i=0;inum_nbrs+1;i++) - binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1; + int8_t binary[PTM_MAX_POINTS]; + for (int i=0;inum_nbrs+1;i++) + binary[i] = numbers[mapping[i]] == numbers[0] ? 0 : 1; - int8_t temp[PTM_MAX_POINTS]; - uint32_t best = 0xFFFFFFFF; - for (int j=0;jnum_mappings;j++) - { - for (int i=0;inum_nbrs+1;i++) - temp[ref->mapping[j][i]] = binary[i]; + int8_t temp[PTM_MAX_POINTS]; + uint32_t best = 0xFFFFFFFF; + for (int j=0;jnum_mappings;j++) + { + for (int i=0;inum_nbrs+1;i++) + temp[ref->mapping[j][i]] = binary[i]; - uint32_t code = 0; - for (int i=0;inum_nbrs+1;i++) - code |= (temp[i] << i); + uint32_t code = 0; + for (int i=0;inum_nbrs+1;i++) + code |= (temp[i] << i); - best = std::min(best, code); - } + best = std::min(best, code); + } - return best; + return best; } int32_t find_alloy_type(const refdata_t* ref, int8_t* mapping, int32_t* numbers) { - for (int i=0;inum_nbrs+1;i++) - if (numbers[i] == -1) - return PTM_ALLOY_NONE; + for (int i=0;inum_nbrs+1;i++) + if (numbers[i] == -1) + return PTM_ALLOY_NONE; - if (test_pure(ref->num_nbrs, numbers)) - return PTM_ALLOY_PURE; + if (test_pure(ref->num_nbrs, numbers)) + return PTM_ALLOY_PURE; - if (!test_binary(ref->num_nbrs, numbers)) - return PTM_ALLOY_NONE; + if (!test_binary(ref->num_nbrs, numbers)) + return PTM_ALLOY_NONE; - uint32_t code = canonical_alloy_representation(ref, mapping, numbers); - for (int i=0;itype == typedata[i][0] && code == typedata[i][2]) - return typedata[i][1]; + uint32_t code = canonical_alloy_representation(ref, mapping, numbers); + for (int i=0;itype == typedata[i][0] && code == typedata[i][2]) + return typedata[i][1]; - if (ref->type == PTM_MATCH_BCC) - if (test_shell_structure(ref, mapping, numbers, 8)) - return PTM_ALLOY_B2; + if (ref->type == PTM_MATCH_BCC) + if (test_shell_structure(ref, mapping, numbers, 8)) + return PTM_ALLOY_B2; - if (ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX) - if (test_shell_structure(ref, mapping, numbers, 4)) - return PTM_ALLOY_SIC; + if (ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX) + if (test_shell_structure(ref, mapping, numbers, 4)) + return PTM_ALLOY_SIC; - if (ref->type == PTM_MATCH_GRAPHENE) - if (test_shell_structure(ref, mapping, numbers, 3)) - return PTM_ALLOY_BN; + if (ref->type == PTM_MATCH_GRAPHENE) + if (test_shell_structure(ref, mapping, numbers, 3)) + return PTM_ALLOY_BN; - return PTM_ALLOY_NONE; + return PTM_ALLOY_NONE; } } diff --git a/src/USER-PTM/ptm_alt_templates.h b/src/USER-PTM/ptm_alt_templates.h index 7a6524e70e..6a348315bf 100644 --- a/src/USER-PTM/ptm_alt_templates.h +++ b/src/USER-PTM/ptm_alt_templates.h @@ -14,113 +14,113 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI const double ptm_template_hcp_alt1[PTM_NUM_POINTS_HCP][3] = { - { 0, 0, 0 }, - { 1, 0, 0 }, - { -0.5, -sqrt(3)/2, 0 }, - { -0.5, -sqrt(3)/6, -sqrt(6)/3 }, - { 0, sqrt(3)/3, -sqrt(6)/3 }, - { 0.5, -sqrt(3)/6, -sqrt(6)/3 }, - { -1, 0, 0 }, - { -0.5, sqrt(3)/2, 0 }, - { 0.5, sqrt(3)/2, 0 }, - { 0.5, -sqrt(3)/2, 0 }, - { 0.5, -sqrt(3)/6, sqrt(6)/3 }, - { 0, sqrt(3)/3, sqrt(6)/3 }, - { -0.5, -sqrt(3)/6, sqrt(6)/3 }, + { 0, 0, 0 }, + { 1, 0, 0 }, + { -0.5, -sqrt(3)/2, 0 }, + { -0.5, -sqrt(3)/6, -sqrt(6)/3 }, + { 0, sqrt(3)/3, -sqrt(6)/3 }, + { 0.5, -sqrt(3)/6, -sqrt(6)/3 }, + { -1, 0, 0 }, + { -0.5, sqrt(3)/2, 0 }, + { 0.5, sqrt(3)/2, 0 }, + { 0.5, -sqrt(3)/2, 0 }, + { 0.5, -sqrt(3)/6, sqrt(6)/3 }, + { 0, sqrt(3)/3, sqrt(6)/3 }, + { -0.5, -sqrt(3)/6, sqrt(6)/3 }, }; const double ptm_template_dcub_alt1[PTM_NUM_POINTS_DCUB][3] = { - { 0, 0, 0 }, - { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, - { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, - { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, - { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, - { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, - { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, - { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, - { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, - { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, - { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, - { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { 0, 0, 0 }, + { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, }; const double ptm_template_dhex_alt1[PTM_NUM_POINTS_DHEX][3] = { - { 0, 0, 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, }; const double ptm_template_dhex_alt2[PTM_NUM_POINTS_DHEX][3] = { - { 0, 0, 0 }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 0, 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, }; const double ptm_template_dhex_alt3[PTM_NUM_POINTS_DHEX][3] = { - { 0, 0, 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 0, 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, -4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, }; const double ptm_template_graphene_alt1[PTM_NUM_POINTS_GRAPHENE][3] = { - { 0, 0, 0 }, - { 3*sqrt(3)/22-9./11, -3./22+3*sqrt(3)/11, 0 }, - { 9./11-3*sqrt(3)/22, -3./22+3*sqrt(3)/11, 0 }, - { 0, -6*sqrt(3)/11+3./11, 0 }, - { -18./11+3*sqrt(3)/11, 0, 0 }, - { 3*sqrt(3)/22-9./11, -9./22+9*sqrt(3)/11, 0 }, - { 9./11-3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, - { -3*sqrt(3)/11+18./11, 0, 0 }, - { 9./11-3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, - { 3*sqrt(3)/22-9./11, -9*sqrt(3)/11+9./22, 0 }, + { 0, 0, 0 }, + { 3*sqrt(3)/22-9./11, -3./22+3*sqrt(3)/11, 0 }, + { 9./11-3*sqrt(3)/22, -3./22+3*sqrt(3)/11, 0 }, + { 0, -6*sqrt(3)/11+3./11, 0 }, + { -18./11+3*sqrt(3)/11, 0, 0 }, + { 3*sqrt(3)/22-9./11, -9./22+9*sqrt(3)/11, 0 }, + { 9./11-3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/11+18./11, 0, 0 }, + { 9./11-3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, + { 3*sqrt(3)/22-9./11, -9*sqrt(3)/11+9./22, 0 }, }; #endif diff --git a/src/USER-PTM/ptm_canonical_coloured.cpp b/src/USER-PTM/ptm_canonical_coloured.cpp index 660c618711..4c794bd9ca 100644 --- a/src/USER-PTM/ptm_canonical_coloured.cpp +++ b/src/USER-PTM/ptm_canonical_coloured.cpp @@ -17,162 +17,162 @@ namespace ptm { static bool weinberg_coloured(int num_nodes, int num_edges, int8_t common[PTM_MAX_NBRS][PTM_MAX_NBRS], int8_t* colours, int8_t* best_code, int8_t* canonical_labelling, int a, int b) { - bool m[PTM_MAX_NBRS][PTM_MAX_NBRS]; - memset(m, 0, sizeof(bool) * PTM_MAX_NBRS * PTM_MAX_NBRS); + bool m[PTM_MAX_NBRS][PTM_MAX_NBRS]; + memset(m, 0, sizeof(bool) * PTM_MAX_NBRS * PTM_MAX_NBRS); - int8_t index[PTM_MAX_NBRS]; - memset(index, -1, sizeof(int8_t) * PTM_MAX_NBRS); + int8_t index[PTM_MAX_NBRS]; + memset(index, -1, sizeof(int8_t) * PTM_MAX_NBRS); - int n = 0; - index[a] = colours[a] * num_nodes + n++; - if (index[a] > best_code[0]) - return false; + int n = 0; + index[a] = colours[a] * num_nodes + n++; + if (index[a] > best_code[0]) + return false; - bool winning = false; - if (index[a] < best_code[0]) - { - best_code[0] = index[a]; - winning = true; - } + bool winning = false; + if (index[a] < best_code[0]) + { + best_code[0] = index[a]; + winning = true; + } - int c = -1; - for (int it=1;it<2*num_edges;it++) - { - bool newvertex = index[b] == -1; + int c = -1; + for (int it=1;it<2*num_edges;it++) + { + bool newvertex = index[b] == -1; - if (newvertex) - index[b] = colours[b] * num_nodes + n++; + if (newvertex) + index[b] = colours[b] * num_nodes + n++; - if (!winning && index[b] > best_code[it]) - return false; + if (!winning && index[b] > best_code[it]) + return false; - if (winning || index[b] < best_code[it]) - { - winning = true; - best_code[it] = index[b]; - } + if (winning || index[b] < best_code[it]) + { + winning = true; + best_code[it] = index[b]; + } - if (newvertex) - { - //When a new vertex is reached, take the right-most edge - //relative to the edge on which the vertex is reached. + if (newvertex) + { + //When a new vertex is reached, take the right-most edge + //relative to the edge on which the vertex is reached. - c = common[a][b]; - } - else if (m[b][a] == false) - { - //When an old vertex is reached on a new path, go back - //in the opposite direction. + c = common[a][b]; + } + else if (m[b][a] == false) + { + //When an old vertex is reached on a new path, go back + //in the opposite direction. - c = a; - } - else - { - //When an old vertex is reached on an old path, leave the - //vertex on the right-most edge that has not previously - //been traversed in that direction. + c = a; + } + else + { + //When an old vertex is reached on an old path, leave the + //vertex on the right-most edge that has not previously + //been traversed in that direction. - c = common[a][b]; - while (m[b][c] == true) - c = common[c][b]; - } + c = common[a][b]; + while (m[b][c] == true) + c = common[c][b]; + } - m[a][b] = true; - a = b; - b = c; - } + m[a][b] = true; + a = b; + b = c; + } - if (winning) - { - memcpy(canonical_labelling, index, sizeof(int8_t) * num_nodes); - return true; - } + if (winning) + { + memcpy(canonical_labelling, index, sizeof(int8_t) * num_nodes); + return true; + } - return false; + return false; } int canonical_form_coloured(int num_facets, int8_t facets[][3], int num_nodes, int8_t* degree, int8_t* colours, int8_t* canonical_labelling, int8_t* best_code, uint64_t* p_hash) { - int8_t common[PTM_MAX_NBRS][PTM_MAX_NBRS] = {{0}}; - int num_edges = 3 * num_facets / 2; - if (!build_facet_map(num_facets, facets, common)) - return -1; + int8_t common[PTM_MAX_NBRS][PTM_MAX_NBRS] = {{0}}; + int num_edges = 3 * num_facets / 2; + if (!build_facet_map(num_facets, facets, common)) + return -1; - memset(best_code, SCHAR_MAX, sizeof(int8_t) * 2 * PTM_MAX_EDGES); + memset(best_code, SCHAR_MAX, sizeof(int8_t) * 2 * PTM_MAX_EDGES); - bool equal = true; - for (int i = 1;i=0;i--) - canonical_labelling[i+1] = (canonical_labelling[i] % num_nodes) + 1; - canonical_labelling[0] = 0; + for (int i = num_nodes-1;i>=0;i--) + canonical_labelling[i+1] = (canonical_labelling[i] % num_nodes) + 1; + canonical_labelling[0] = 0; - uint64_t hash = 0; - for (int i = 0;i<2 * num_edges;i++) - { - uint64_t e = best_code[i]; - e += i % 8; - e &= 0xF; - e <<= (4 * i) % 64; - hash ^= e; - } + uint64_t hash = 0; + for (int i = 0;i<2 * num_edges;i++) + { + uint64_t e = best_code[i]; + e += i % 8; + e &= 0xF; + e <<= (4 * i) % 64; + hash ^= e; + } - *p_hash = hash; - return PTM_NO_ERROR; + *p_hash = hash; + return PTM_NO_ERROR; } } diff --git a/src/USER-PTM/ptm_constants.h b/src/USER-PTM/ptm_constants.h index f607a9132d..c3882f622c 100644 --- a/src/USER-PTM/ptm_constants.h +++ b/src/USER-PTM/ptm_constants.h @@ -15,45 +15,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI //------------------------------------ // definitions //------------------------------------ -#define PTM_NO_ERROR 0 +#define PTM_NO_ERROR 0 -#define PTM_CHECK_FCC (1 << 0) -#define PTM_CHECK_HCP (1 << 1) -#define PTM_CHECK_BCC (1 << 2) -#define PTM_CHECK_ICO (1 << 3) -#define PTM_CHECK_SC (1 << 4) -#define PTM_CHECK_DCUB (1 << 5) -#define PTM_CHECK_DHEX (1 << 6) -#define PTM_CHECK_GRAPHENE (1 << 7) -#define PTM_CHECK_DEFAULT (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC) -#define PTM_CHECK_ALL (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC | PTM_CHECK_DCUB | PTM_CHECK_DHEX | PTM_CHECK_GRAPHENE) +#define PTM_CHECK_FCC (1 << 0) +#define PTM_CHECK_HCP (1 << 1) +#define PTM_CHECK_BCC (1 << 2) +#define PTM_CHECK_ICO (1 << 3) +#define PTM_CHECK_SC (1 << 4) +#define PTM_CHECK_DCUB (1 << 5) +#define PTM_CHECK_DHEX (1 << 6) +#define PTM_CHECK_GRAPHENE (1 << 7) +#define PTM_CHECK_DEFAULT (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC) +#define PTM_CHECK_ALL (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | PTM_CHECK_BCC | PTM_CHECK_DCUB | PTM_CHECK_DHEX | PTM_CHECK_GRAPHENE) -#define PTM_MATCH_NONE 0 -#define PTM_MATCH_FCC 1 -#define PTM_MATCH_HCP 2 -#define PTM_MATCH_BCC 3 -#define PTM_MATCH_ICO 4 -#define PTM_MATCH_SC 5 -#define PTM_MATCH_DCUB 6 -#define PTM_MATCH_DHEX 7 -#define PTM_MATCH_GRAPHENE 8 +#define PTM_MATCH_NONE 0 +#define PTM_MATCH_FCC 1 +#define PTM_MATCH_HCP 2 +#define PTM_MATCH_BCC 3 +#define PTM_MATCH_ICO 4 +#define PTM_MATCH_SC 5 +#define PTM_MATCH_DCUB 6 +#define PTM_MATCH_DHEX 7 +#define PTM_MATCH_GRAPHENE 8 -#define PTM_ALLOY_NONE 0 -#define PTM_ALLOY_PURE 1 -#define PTM_ALLOY_L10 2 -#define PTM_ALLOY_L12_CU 3 -#define PTM_ALLOY_L12_AU 4 -#define PTM_ALLOY_B2 5 -#define PTM_ALLOY_SIC 6 -#define PTM_ALLOY_BN 7 +#define PTM_ALLOY_NONE 0 +#define PTM_ALLOY_PURE 1 +#define PTM_ALLOY_L10 2 +#define PTM_ALLOY_L12_CU 3 +#define PTM_ALLOY_L12_AU 4 +#define PTM_ALLOY_B2 5 +#define PTM_ALLOY_SIC 6 +#define PTM_ALLOY_BN 7 #define PTM_MAX_INPUT_POINTS 19 -#define PTM_MAX_NBRS 16 -#define PTM_MAX_POINTS (PTM_MAX_NBRS + 1) -#define PTM_MAX_FACETS 28 //2 * PTM_MAX_NBRS - 4 -#define PTM_MAX_EDGES 42 //3 * PTM_MAX_NBRS - 6 +#define PTM_MAX_NBRS 16 +#define PTM_MAX_POINTS (PTM_MAX_NBRS + 1) +#define PTM_MAX_FACETS 28 //2 * PTM_MAX_NBRS - 4 +#define PTM_MAX_EDGES 42 //3 * PTM_MAX_NBRS - 6 //------------------------------------ @@ -86,132 +86,132 @@ const int ptm_num_nbrs[9] = {0, PTM_NUM_NBRS_FCC, PTM_NUM_NBRS_HCP, PTM_NUM_NBRS //these point sets have barycentre {0, 0, 0} and are scaled such that the mean neighbour distance is 1 const double ptm_template_fcc[PTM_NUM_POINTS_FCC][3] = { - { 0, 0, 0 }, - { sqrt(2)/2, sqrt(2)/2, 0 }, - { 0, sqrt(2)/2, sqrt(2)/2 }, - { sqrt(2)/2, 0, sqrt(2)/2 }, - { -sqrt(2)/2, -sqrt(2)/2, 0 }, - { 0, -sqrt(2)/2, -sqrt(2)/2 }, - { -sqrt(2)/2, 0, -sqrt(2)/2 }, - { -sqrt(2)/2, sqrt(2)/2, 0 }, - { 0, -sqrt(2)/2, sqrt(2)/2 }, - { -sqrt(2)/2, 0, sqrt(2)/2 }, - { sqrt(2)/2, -sqrt(2)/2, 0 }, - { 0, sqrt(2)/2, -sqrt(2)/2 }, - { sqrt(2)/2, 0, -sqrt(2)/2 }, + { 0, 0, 0 }, + { sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, sqrt(2)/2 }, + { sqrt(2)/2, 0, sqrt(2)/2 }, + { -sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, -sqrt(2)/2, -sqrt(2)/2 }, + { -sqrt(2)/2, 0, -sqrt(2)/2 }, + { -sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, -sqrt(2)/2, sqrt(2)/2 }, + { -sqrt(2)/2, 0, sqrt(2)/2 }, + { sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, -sqrt(2)/2 }, + { sqrt(2)/2, 0, -sqrt(2)/2 }, }; const double ptm_template_hcp[PTM_NUM_POINTS_HCP][3] = { - { 0, 0, 0 }, - { 0.5, -sqrt(3)/2, 0 }, - { -1, 0, 0 }, - { -0.5, sqrt(3)/6, -sqrt(6)/3 }, - { 0.5, sqrt(3)/6, -sqrt(6)/3 }, - { 0, -sqrt(3)/3, -sqrt(6)/3 }, - { -0.5, sqrt(3)/2, 0 }, - { 0.5, sqrt(3)/2, 0 }, - { 1, 0, 0 }, - { -0.5, -sqrt(3)/2, 0 }, - { 0, -sqrt(3)/3, sqrt(6)/3 }, - { 0.5, sqrt(3)/6, sqrt(6)/3 }, - { -0.5, sqrt(3)/6, sqrt(6)/3 }, + { 0, 0, 0 }, + { 0.5, -sqrt(3)/2, 0 }, + { -1, 0, 0 }, + { -0.5, sqrt(3)/6, -sqrt(6)/3 }, + { 0.5, sqrt(3)/6, -sqrt(6)/3 }, + { 0, -sqrt(3)/3, -sqrt(6)/3 }, + { -0.5, sqrt(3)/2, 0 }, + { 0.5, sqrt(3)/2, 0 }, + { 1, 0, 0 }, + { -0.5, -sqrt(3)/2, 0 }, + { 0, -sqrt(3)/3, sqrt(6)/3 }, + { 0.5, sqrt(3)/6, sqrt(6)/3 }, + { -0.5, sqrt(3)/6, sqrt(6)/3 }, }; const double ptm_template_bcc[PTM_NUM_POINTS_BCC][3] = { - { 0, 0, 0 }, - { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, - { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, - { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, - { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, - { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, - { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, - { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, - { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, - { 14*sqrt(3)/3-7, 0, 0 }, - { 7-14*sqrt(3)/3, 0, 0 }, - { 0, 14*sqrt(3)/3-7, 0 }, - { 0, 7-14*sqrt(3)/3, 0 }, - { 0, 0, 14*sqrt(3)/3-7 }, - { 0, 0, 7-14*sqrt(3)/3 }, + { 0, 0, 0 }, + { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, + { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2 }, + { 7*sqrt(3)/3-7./2, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, + { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, + { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2 }, + { 7./2-7*sqrt(3)/3, 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3 }, + { 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, + { 7*sqrt(3)/3-7./2, 7./2-7*sqrt(3)/3, 7./2-7*sqrt(3)/3 }, + { 14*sqrt(3)/3-7, 0, 0 }, + { 7-14*sqrt(3)/3, 0, 0 }, + { 0, 14*sqrt(3)/3-7, 0 }, + { 0, 7-14*sqrt(3)/3, 0 }, + { 0, 0, 14*sqrt(3)/3-7 }, + { 0, 0, 7-14*sqrt(3)/3 }, }; const double ptm_template_ico[PTM_NUM_POINTS_ICO][3] = { - { 0, 0, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 }, - { -sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, - { sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, - { 0, -2*sqrt(5)/5, -sqrt(5)/5 }, - { 0, 2*sqrt(5)/5, sqrt(5)/5 }, - { sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, - { -sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, - { -sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, - { sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, - { sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, - { -sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, + { 0, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + { -sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, + { sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, + { 0, -2*sqrt(5)/5, -sqrt(5)/5 }, + { 0, 2*sqrt(5)/5, sqrt(5)/5 }, + { sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, + { -sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, + { -sqrt((5+sqrt(5))/10), -(5-sqrt(5))/10, -sqrt(5)/5 }, + { sqrt((5+sqrt(5))/10), (5-sqrt(5))/10, sqrt(5)/5 }, + { sqrt((5-sqrt(5))/10), (5+sqrt(5))/10, -sqrt(5)/5 }, + { -sqrt((5-sqrt(5))/10), -(5+sqrt(5))/10, sqrt(5)/5 }, }; const double ptm_template_sc[PTM_NUM_POINTS_SC][3] = { - { 0, 0, 0 }, - { 0, 0, -1 }, - { 0, 0, 1 }, - { 0, -1, 0 }, - { 0, 1, 0 }, - { -1, 0, 0 }, - { 1, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, -1 }, + { 0, 0, 1 }, + { 0, -1, 0 }, + { 0, 1, 0 }, + { -1, 0, 0 }, + { 1, 0, 0 }, }; const double ptm_template_dcub[PTM_NUM_POINTS_DCUB][3] = { - { 0, 0, 0 }, - { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, - { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, - { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, - { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, - { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, - { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, - { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, - { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, - { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, - { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, - { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { 0, 0, 0 }, + { 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)) }, + { -4/(sqrt(3)+6*sqrt(2)), 4/(sqrt(3)+6*sqrt(2)), -4/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { 0, -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, + { 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 0, 8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 0, -8/(sqrt(3)+6*sqrt(2)) }, + { -8/(sqrt(3)+6*sqrt(2)), 8/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, 8/(sqrt(3)+6*sqrt(2)), -8/(sqrt(3)+6*sqrt(2)) }, }; const double ptm_template_dhex[PTM_NUM_POINTS_DHEX][3] = { - { 0, 0, 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, - { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, - { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, - { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, - { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, - { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 0, 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -4*sqrt(3)/(3*sqrt(3)+18*sqrt(2)) }, + { 0, 0, 4*sqrt(3)/(sqrt(3)+6*sqrt(2)) }, + { -8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), -4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), -16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(sqrt(3)+6*sqrt(2)), 0 }, + { 8*sqrt(2)/(sqrt(3)+6*sqrt(2)), 0, 0 }, + { 0, -8*sqrt(6)/(3*sqrt(3)+18*sqrt(2)), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { 4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, + { -4*sqrt(2)/(sqrt(3)+6*sqrt(2)), 4*sqrt(6)/(3*(sqrt(3)+6*sqrt(2))), 16*sqrt(3)/(3*(sqrt(3)+6*sqrt(2))) }, }; const double ptm_template_graphene[PTM_NUM_POINTS_GRAPHENE][3] = { - { 0, 0, 0 }, - { 0, -3./11+6*sqrt(3)/11, 0 }, - { -3*sqrt(3)/22+9./11, -3*sqrt(3)/11+3./22, 0 }, - { -9./11+3*sqrt(3)/22, -3*sqrt(3)/11+3./22, 0 }, - { -9./11+3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, - { -3*sqrt(3)/22+9./11, -9./22+9*sqrt(3)/11, 0 }, - { -3*sqrt(3)/11+18./11, 0, 0 }, - { -3*sqrt(3)/22+9./11, -9*sqrt(3)/11+9./22, 0 }, - { -9./11+3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, - { -18./11+3*sqrt(3)/11, 0, 0 }, + { 0, 0, 0 }, + { 0, -3./11+6*sqrt(3)/11, 0 }, + { -3*sqrt(3)/22+9./11, -3*sqrt(3)/11+3./22, 0 }, + { -9./11+3*sqrt(3)/22, -3*sqrt(3)/11+3./22, 0 }, + { -9./11+3*sqrt(3)/22, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/22+9./11, -9./22+9*sqrt(3)/11, 0 }, + { -3*sqrt(3)/11+18./11, 0, 0 }, + { -3*sqrt(3)/22+9./11, -9*sqrt(3)/11+9./22, 0 }, + { -9./11+3*sqrt(3)/22, -9*sqrt(3)/11+9./22, 0 }, + { -18./11+3*sqrt(3)/11, 0, 0 }, }; #endif diff --git a/src/USER-PTM/ptm_convex_hull_incremental.cpp b/src/USER-PTM/ptm_convex_hull_incremental.cpp index e7f93eea06..fb0c95201b 100644 --- a/src/USER-PTM/ptm_convex_hull_incremental.cpp +++ b/src/USER-PTM/ptm_convex_hull_incremental.cpp @@ -24,351 +24,351 @@ namespace ptm { static double norm_squared(double* p) { - double x = p[0]; - double y = p[1]; - double z = p[2]; + double x = p[0]; + double y = p[1]; + double z = p[2]; - return x*x + y*y + z*z; + return x*x + y*y + z*z; } static double dot_product(const double* a, const double* b) { - return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } static void cross_product(double* a, double* b, double* c) { - c[0] = a[1] * b[2] - a[2] * b[1]; - c[1] = a[2] * b[0] - a[0] * b[2]; - c[2] = a[0] * b[1] - a[1] * b[0]; + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; } static void calculate_plane_normal(const double (*points)[3], int a, int b, int c, double* plane_normal) { - double u[3] = { points[b][0] - points[a][0], - points[b][1] - points[a][1], - points[b][2] - points[a][2] }; + double u[3] = { points[b][0] - points[a][0], + points[b][1] - points[a][1], + points[b][2] - points[a][2] }; - double v[3] = { points[c][0] - points[a][0], - points[c][1] - points[a][1], - points[c][2] - points[a][2] }; + double v[3] = { points[c][0] - points[a][0], + points[c][1] - points[a][1], + points[c][2] - points[a][2] }; - cross_product(u, v, plane_normal); - double norm = sqrt(norm_squared(plane_normal)); - plane_normal[0] /= norm; - plane_normal[1] /= norm; - plane_normal[2] /= norm; + cross_product(u, v, plane_normal); + double norm = sqrt(norm_squared(plane_normal)); + plane_normal[0] /= norm; + plane_normal[1] /= norm; + plane_normal[2] /= norm; } static double point_plane_distance(const double* w, const double* plane_point, const double* plane_cross) { - return plane_cross[0] * (plane_point[0] - w[0]) - + plane_cross[1] * (plane_point[1] - w[1]) - + plane_cross[2] * (plane_point[2] - w[2]); + return plane_cross[0] * (plane_point[0] - w[0]) + + plane_cross[1] * (plane_point[1] - w[1]) + + plane_cross[2] * (plane_point[2] - w[2]); } static bool calc_max_extent(int num_points, const double (*points)[3], int* min_index, int* max_index) { - for (int j=0;j<3;j++) - { - double dmin = DBL_MAX, dmax = -DBL_MAX; - int imin = 0, imax = 0; + for (int j=0;j<3;j++) + { + double dmin = DBL_MAX, dmax = -DBL_MAX; + int imin = 0, imax = 0; - for (int i = 0;i dmax) - { - dmax = d; - imax = i; - } - } + for (int i = 0;i dmax) + { + dmax = d; + imax = i; + } + } - if (imin == imax) - return false; //degenerate point set + if (imin == imax) + return false; //degenerate point set - min_index[j] = imin; - max_index[j] = imax; - } + min_index[j] = imin; + max_index[j] = imax; + } - return true; + return true; } static bool find_third_point(int num_points, const double (*points)[3], int a, int b, int* p_c) { - const double* x1 = points[a]; - const double* x2 = points[b]; + const double* x1 = points[a]; + const double* x2 = points[b]; - double x2x1[3] = {x2[0] - x1[0], x2[1] - x1[1], x2[2] - x1[2]}; - double ns_x2x1 = norm_squared(x2x1); + double x2x1[3] = {x2[0] - x1[0], x2[1] - x1[1], x2[2] - x1[2]}; + double ns_x2x1 = norm_squared(x2x1); - int bi = -1; - double max_dist = 0.0; - for (int i = 0;i max_dist) - { - max_dist = dist; - bi = i; - } - } + if (dist > max_dist) + { + max_dist = dist; + bi = i; + } + } - *p_c = bi; - return max_dist > TOLERANCE; + *p_c = bi; + return max_dist > TOLERANCE; } static bool find_fourth_point(int num_points, const double (*points)[3], int a, int b, int c, int* p_d) { - double plane_normal[3]; - calculate_plane_normal(points, a, b, c, plane_normal); + double plane_normal[3]; + calculate_plane_normal(points, a, b, c, plane_normal); - int bi = -1; - double max_dist = 0.0; - for (int i = 0;i max_dist) - { - max_dist = dist; - bi = i; - } - } + const double* x0 = points[i]; + double dist = fabs(point_plane_distance(x0, points[a], plane_normal)); + if (dist > max_dist) + { + max_dist = dist; + bi = i; + } + } - *p_d = bi; - return max_dist > TOLERANCE; + *p_d = bi; + return max_dist > TOLERANCE; } static int initial_simplex(int num_points, const double (*points)[3], int* initial_vertices) { - int min_index[3] = {0}; - int max_index[3] = {0}; - if (!calc_max_extent(num_points, points, min_index, max_index)) - return -1; + int min_index[3] = {0}; + int max_index[3] = {0}; + if (!calc_max_extent(num_points, points, min_index, max_index)) + return -1; - int bi = -1; - double max_dist = 0.0; - for (int i = 0;i<3;i++) - { - int a = min_index[i], b = max_index[i]; - double delta[3] = { points[a][0] - points[b][0], - points[a][1] - points[b][1], - points[a][2] - points[b][2] }; - double dist = norm_squared(delta); - if (dist > max_dist) - { - bi = i; - max_dist = dist; - } - } + int bi = -1; + double max_dist = 0.0; + for (int i = 0;i<3;i++) + { + int a = min_index[i], b = max_index[i]; + double delta[3] = { points[a][0] - points[b][0], + points[a][1] - points[b][1], + points[a][2] - points[b][2] }; + double dist = norm_squared(delta); + if (dist > max_dist) + { + bi = i; + max_dist = dist; + } + } - //first two points are (a, b) - int a = min_index[bi], b = max_index[bi], c = -1, d = -1; + //first two points are (a, b) + int a = min_index[bi], b = max_index[bi], c = -1, d = -1; - if (!find_third_point(num_points, points, a, b, &c)) - return -2; + if (!find_third_point(num_points, points, a, b, &c)) + return -2; - if (!find_fourth_point(num_points, points, a, b, c, &d)) - return -3; + if (!find_fourth_point(num_points, points, a, b, c, &d)) + return -3; - initial_vertices[0] = a; - initial_vertices[1] = b; - initial_vertices[2] = c; - initial_vertices[3] = d; - return 0; + initial_vertices[0] = a; + initial_vertices[1] = b; + initial_vertices[2] = c; + initial_vertices[3] = d; + return 0; } static bool visible(const double* w, const double* plane_point, const double* plane_normal) { - return point_plane_distance(w, plane_point, plane_normal) > 0; + return point_plane_distance(w, plane_point, plane_normal) > 0; } void add_facet(const double (*points)[3], int a, int b, int c, int8_t* facet, double* plane_normal, double* barycentre) { - calculate_plane_normal(points, a, b, c, plane_normal); - if (visible(barycentre, points[a], plane_normal)) - { - plane_normal[0] = -plane_normal[0]; - plane_normal[1] = -plane_normal[1]; - plane_normal[2] = -plane_normal[2]; + calculate_plane_normal(points, a, b, c, plane_normal); + if (visible(barycentre, points[a], plane_normal)) + { + plane_normal[0] = -plane_normal[0]; + plane_normal[1] = -plane_normal[1]; + plane_normal[2] = -plane_normal[2]; - facet[0] = b; - facet[1] = a; - facet[2] = c; - } - else - { - facet[0] = a; - facet[1] = b; - facet[2] = c; - } + facet[0] = b; + facet[1] = a; + facet[2] = c; + } + else + { + facet[0] = a; + facet[1] = b; + facet[2] = c; + } } static int initialize_convex_hull(int num_points, const double (*points)[3], int8_t facets[][3], double plane_normal[][3], bool* processed, int* initial_vertices, double* barycentre) { - memset(processed, 0, PTM_MAX_POINTS * sizeof(bool)); - memset(barycentre, 0, 3 * sizeof(double)); - int ret = initial_simplex(num_points, points, initial_vertices); - if (ret != 0) - return ret; + memset(processed, 0, PTM_MAX_POINTS * sizeof(bool)); + memset(barycentre, 0, 3 * sizeof(double)); + int ret = initial_simplex(num_points, points, initial_vertices); + if (ret != 0) + return ret; - for (int i = 0;i<4;i++) - { - int a = initial_vertices[i]; - processed[a] = true; + for (int i = 0;i<4;i++) + { + int a = initial_vertices[i]; + processed[a] = true; - barycentre[0] += points[a][0]; - barycentre[1] += points[a][1]; - barycentre[2] += points[a][2]; - } - barycentre[0] /= 4; - barycentre[1] /= 4; - barycentre[2] /= 4; + barycentre[0] += points[a][0]; + barycentre[1] += points[a][1]; + barycentre[2] += points[a][2]; + } + barycentre[0] /= 4; + barycentre[1] /= 4; + barycentre[2] /= 4; - add_facet(points, initial_vertices[0], initial_vertices[1], initial_vertices[2], facets[0], plane_normal[0], barycentre); - add_facet(points, initial_vertices[0], initial_vertices[1], initial_vertices[3], facets[1], plane_normal[1], barycentre); - add_facet(points, initial_vertices[0], initial_vertices[2], initial_vertices[3], facets[2], plane_normal[2], barycentre); - add_facet(points, initial_vertices[1], initial_vertices[2], initial_vertices[3], facets[3], plane_normal[3], barycentre); - return 0; + add_facet(points, initial_vertices[0], initial_vertices[1], initial_vertices[2], facets[0], plane_normal[0], barycentre); + add_facet(points, initial_vertices[0], initial_vertices[1], initial_vertices[3], facets[1], plane_normal[1], barycentre); + add_facet(points, initial_vertices[0], initial_vertices[2], initial_vertices[3], facets[2], plane_normal[2], barycentre); + add_facet(points, initial_vertices[1], initial_vertices[2], initial_vertices[3], facets[3], plane_normal[3], barycentre); + return 0; } int get_convex_hull(int num_points, const double (*points)[3], convexhull_t* ch, int8_t simplex[][3]) { - assert( num_points == PTM_NUM_POINTS_FCC - || num_points == PTM_NUM_POINTS_HCP - || num_points == PTM_NUM_POINTS_BCC - || num_points == PTM_NUM_POINTS_ICO - || num_points == PTM_NUM_POINTS_SC - || num_points == PTM_NUM_POINTS_DCUB - || num_points == PTM_NUM_POINTS_DHEX); + assert( num_points == PTM_NUM_POINTS_FCC + || num_points == PTM_NUM_POINTS_HCP + || num_points == PTM_NUM_POINTS_BCC + || num_points == PTM_NUM_POINTS_ICO + || num_points == PTM_NUM_POINTS_SC + || num_points == PTM_NUM_POINTS_DCUB + || num_points == PTM_NUM_POINTS_DHEX); - int ret = 0; - int num_prev = ch->num_prev; - ch->num_prev = num_points; - if (!ch->ok || 0) - { - ret = initialize_convex_hull(num_points, points, ch->facets, ch->plane_normal, ch->processed, ch->initial_vertices, ch->barycentre); - if (ret != 0) - return ret; + int ret = 0; + int num_prev = ch->num_prev; + ch->num_prev = num_points; + if (!ch->ok || 0) + { + ret = initialize_convex_hull(num_points, points, ch->facets, ch->plane_normal, ch->processed, ch->initial_vertices, ch->barycentre); + if (ret != 0) + return ret; - ch->num_facets = 4; - num_prev = 0; - } + ch->num_facets = 4; + num_prev = 0; + } - for (int i = num_prev;iprocessed[i]) - continue; - ch->processed[i] = true; + for (int i = num_prev;iprocessed[i]) + continue; + ch->processed[i] = true; - int num_to_add = 0; - int8_t to_add[PTM_MAX_FACETS][3]; - int8_t edge_visible[PTM_MAX_POINTS][PTM_MAX_POINTS]; - memset(edge_visible, 0, sizeof(int8_t) * PTM_MAX_POINTS * PTM_MAX_POINTS); - for (int j = 0;jnum_facets;j++) - { - int a = ch->facets[j][0]; - int b = ch->facets[j][1]; - int c = ch->facets[j][2]; + int num_to_add = 0; + int8_t to_add[PTM_MAX_FACETS][3]; + int8_t edge_visible[PTM_MAX_POINTS][PTM_MAX_POINTS]; + memset(edge_visible, 0, sizeof(int8_t) * PTM_MAX_POINTS * PTM_MAX_POINTS); + for (int j = 0;jnum_facets;j++) + { + int a = ch->facets[j][0]; + int b = ch->facets[j][1]; + int c = ch->facets[j][2]; - int u = 0, v = 0, w = 0; + int u = 0, v = 0, w = 0; - double distance = point_plane_distance(points[i], points[a], ch->plane_normal[j]); - bool vis = distance > TOLERANCE; - if (vis) - { - u = edge_visible[a][b] |= VISIBLE; - edge_visible[b][a] |= VISIBLE; + double distance = point_plane_distance(points[i], points[a], ch->plane_normal[j]); + bool vis = distance > TOLERANCE; + if (vis) + { + u = edge_visible[a][b] |= VISIBLE; + edge_visible[b][a] |= VISIBLE; - v = edge_visible[b][c] |= VISIBLE; - edge_visible[c][b] |= VISIBLE; + v = edge_visible[b][c] |= VISIBLE; + edge_visible[c][b] |= VISIBLE; - w = edge_visible[c][a] |= VISIBLE; - edge_visible[a][c] |= VISIBLE; + w = edge_visible[c][a] |= VISIBLE; + edge_visible[a][c] |= VISIBLE; - memcpy(ch->facets[j], ch->facets[ch->num_facets-1], 3 * sizeof(int8_t)); - memcpy(ch->plane_normal[j], ch->plane_normal[ch->num_facets-1], 3 * sizeof(double)); - ch->num_facets--; - j--; - } - else - { - u = edge_visible[a][b] |= INVISIBLE; - edge_visible[b][a] |= INVISIBLE; + memcpy(ch->facets[j], ch->facets[ch->num_facets-1], 3 * sizeof(int8_t)); + memcpy(ch->plane_normal[j], ch->plane_normal[ch->num_facets-1], 3 * sizeof(double)); + ch->num_facets--; + j--; + } + else + { + u = edge_visible[a][b] |= INVISIBLE; + edge_visible[b][a] |= INVISIBLE; - v = edge_visible[b][c] |= INVISIBLE; - edge_visible[c][b] |= INVISIBLE; + v = edge_visible[b][c] |= INVISIBLE; + edge_visible[c][b] |= INVISIBLE; - w = edge_visible[c][a] |= INVISIBLE; - edge_visible[a][c] |= INVISIBLE; - } + w = edge_visible[c][a] |= INVISIBLE; + edge_visible[a][c] |= INVISIBLE; + } - if (u == BOTH) - { - to_add[num_to_add][0] = i; - to_add[num_to_add][1] = a; - to_add[num_to_add][2] = b; - num_to_add++; - } + if (u == BOTH) + { + to_add[num_to_add][0] = i; + to_add[num_to_add][1] = a; + to_add[num_to_add][2] = b; + num_to_add++; + } - if (v == BOTH) - { - to_add[num_to_add][0] = i; - to_add[num_to_add][1] = b; - to_add[num_to_add][2] = c; - num_to_add++; - } + if (v == BOTH) + { + to_add[num_to_add][0] = i; + to_add[num_to_add][1] = b; + to_add[num_to_add][2] = c; + num_to_add++; + } - if (w == BOTH) - { - to_add[num_to_add][0] = i; - to_add[num_to_add][1] = c; - to_add[num_to_add][2] = a; - num_to_add++; - } - } + if (w == BOTH) + { + to_add[num_to_add][0] = i; + to_add[num_to_add][1] = c; + to_add[num_to_add][2] = a; + num_to_add++; + } + } - for (int j = 0;jnum_facets >= PTM_MAX_FACETS) - return -4; + for (int j = 0;jnum_facets >= PTM_MAX_FACETS) + return -4; - add_facet(points, to_add[j][0], to_add[j][1], to_add[j][2], ch->facets[ch->num_facets], ch->plane_normal[ch->num_facets], ch->barycentre); ch->num_facets++; - } - } + add_facet(points, to_add[j][0], to_add[j][1], to_add[j][2], ch->facets[ch->num_facets], ch->plane_normal[ch->num_facets], ch->barycentre); ch->num_facets++; + } + } - for (int i=0;inum_facets;i++) - { - int a = ch->facets[i][0]; - int b = ch->facets[i][1]; - int c = ch->facets[i][2]; - if (a == 0 || b == 0 || c == 0) - return 1; //central atom contained in convex hull + for (int i=0;inum_facets;i++) + { + int a = ch->facets[i][0]; + int b = ch->facets[i][1]; + int c = ch->facets[i][2]; + if (a == 0 || b == 0 || c == 0) + return 1; //central atom contained in convex hull - simplex[i][0] = a - 1; - simplex[i][1] = b - 1; - simplex[i][2] = c - 1; - } + simplex[i][0] = a - 1; + simplex[i][1] = b - 1; + simplex[i][2] = c - 1; + } - return ret; + return ret; } } diff --git a/src/USER-PTM/ptm_convex_hull_incremental.h b/src/USER-PTM/ptm_convex_hull_incremental.h index da4a810676..1d51ae4dec 100644 --- a/src/USER-PTM/ptm_convex_hull_incremental.h +++ b/src/USER-PTM/ptm_convex_hull_incremental.h @@ -19,14 +19,14 @@ namespace ptm { typedef struct { - int8_t facets[PTM_MAX_FACETS][3]; - double plane_normal[PTM_MAX_FACETS][3]; - bool processed[PTM_MAX_POINTS]; - int initial_vertices[4]; - double barycentre[3]; - int num_facets; - int num_prev; - bool ok; + int8_t facets[PTM_MAX_FACETS][3]; + double plane_normal[PTM_MAX_FACETS][3]; + bool processed[PTM_MAX_POINTS]; + int initial_vertices[4]; + double barycentre[3]; + int num_facets; + int num_prev; + bool ok; } convexhull_t; diff --git a/src/USER-PTM/ptm_deformation_gradient.cpp b/src/USER-PTM/ptm_deformation_gradient.cpp index afa592f2c4..2715c21aab 100644 --- a/src/USER-PTM/ptm_deformation_gradient.cpp +++ b/src/USER-PTM/ptm_deformation_gradient.cpp @@ -13,36 +13,36 @@ namespace ptm { void calculate_deformation_gradient(int num_points, const double (*ideal_points)[3], int8_t* mapping, double (*normalized)[3], const double (*penrose)[3], double* F, double* res) { - for (int i = 0;i<3;i++) - { - for (int j = 0;j<3;j++) - { - double acc = 0.0; - for (int k = 0;k static double calculate_interatomic_distance(int type, double scale) { - assert(type >= 1 && type <= 8); + assert(type >= 1 && type <= 8); - // these values should be equal to norm(template[1]) - double c[9] = {0, - 1, - 1, - (7. - 3.5 * sqrt(3)), - 1, - 1, - sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), - sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), - -3. / 11 + 6 * sqrt(3) / 11}; - return c[type] / scale; + // these values should be equal to norm(template[1]) + double c[9] = {0, + 1, + 1, + (7. - 3.5 * sqrt(3)), + 1, + 1, + sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), + sqrt(3) * 4. / (6 * sqrt(2) + sqrt(3)), + -3. / 11 + 6 * sqrt(3) / 11}; + return c[type] / scale; } static double calculate_lattice_constant(int type, double interatomic_distance) { - assert(type >= 1 && type <= 8); - double c[9] = {0, 2 / sqrt(2), 2 / sqrt(2), 2. / sqrt(3), 2 / sqrt(2), - 1, 4 / sqrt(3), 4 / sqrt(3), sqrt(3)}; - return c[type] * interatomic_distance; + assert(type >= 1 && type <= 8); + double c[9] = {0, 2 / sqrt(2), 2 / sqrt(2), 2. / sqrt(3), 2 / sqrt(2), + 1, 4 / sqrt(3), 4 / sqrt(3), sqrt(3)}; + return c[type] * interatomic_distance; } static int rotate_into_fundamental_zone(int type, bool output_conventional_orientation, double *q) { - if (type == PTM_MATCH_SC) - return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_FCC) - return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_BCC) - return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - if (type == PTM_MATCH_ICO) - return ptm::rotate_quaternion_into_icosahedral_fundamental_zone(q); + if (type == PTM_MATCH_SC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_FCC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_BCC) + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + if (type == PTM_MATCH_ICO) + return ptm::rotate_quaternion_into_icosahedral_fundamental_zone(q); - if (type == PTM_MATCH_HCP || type == PTM_MATCH_GRAPHENE) { - if (output_conventional_orientation) { - return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); - } else { - return ptm::rotate_quaternion_into_hcp_fundamental_zone(q); - } - } + if (type == PTM_MATCH_HCP || type == PTM_MATCH_GRAPHENE) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_hcp_fundamental_zone(q); + } + } - if (type == PTM_MATCH_DCUB) { - if (output_conventional_orientation) { - return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); - } else { - return ptm::rotate_quaternion_into_diamond_cubic_fundamental_zone(q); - } - } + if (type == PTM_MATCH_DCUB) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_cubic_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_diamond_cubic_fundamental_zone(q); + } + } - if (type == PTM_MATCH_DHEX) { - if (output_conventional_orientation) { - return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); - } else { - return ptm::rotate_quaternion_into_diamond_hexagonal_fundamental_zone(q); - } - } + if (type == PTM_MATCH_DHEX) { + if (output_conventional_orientation) { + return ptm::rotate_quaternion_into_hcp_conventional_fundamental_zone(q); + } else { + return ptm::rotate_quaternion_into_diamond_hexagonal_fundamental_zone(q); + } + } - return -1; + return -1; } static void output_data(ptm::result_t *res, double (*points)[3], @@ -97,94 +97,94 @@ static void output_data(ptm::result_t *res, double (*points)[3], double *q, double *F, double *F_res, double *U, double *P, double *p_interatomic_distance, double *p_lattice_constant, size_t *output_indices) { - const ptm::refdata_t *ref = res->ref_struct; - if (ref == NULL) - return; + const ptm::refdata_t *ref = res->ref_struct; + if (ref == NULL) + return; - *p_type = ref->type; - if (p_alloy_type != NULL) - *p_alloy_type = ptm::find_alloy_type(ref, res->mapping, numbers); + *p_type = ref->type; + if (p_alloy_type != NULL) + *p_alloy_type = ptm::find_alloy_type(ref, res->mapping, numbers); - int8_t temp[PTM_MAX_POINTS]; - memset(temp, -1, PTM_MAX_POINTS * sizeof(int8_t)); - int bi = rotate_into_fundamental_zone(ref->type, - output_conventional_orientation, res->q); - //todo: return if bi == -1 - if (bi != -1) - { - if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) - { - for (int i = 0; i < ref->num_nbrs + 1; i++) - temp[ref->mapping_conventional[bi][i]] = res->mapping[i]; - } - else - { - for (int i = 0; i < ref->num_nbrs + 1; i++) - temp[ref->mapping[bi][i]] = res->mapping[i]; - } - } + int8_t temp[PTM_MAX_POINTS]; + memset(temp, -1, PTM_MAX_POINTS * sizeof(int8_t)); + int bi = rotate_into_fundamental_zone(ref->type, + output_conventional_orientation, res->q); + //todo: return if bi == -1 + if (bi != -1) + { + if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) + { + for (int i = 0; i < ref->num_nbrs + 1; i++) + temp[ref->mapping_conventional[bi][i]] = res->mapping[i]; + } + else + { + for (int i = 0; i < ref->num_nbrs + 1; i++) + temp[ref->mapping[bi][i]] = res->mapping[i]; + } + } - memcpy(res->mapping, temp, (ref->num_nbrs + 1) * sizeof(int8_t)); + memcpy(res->mapping, temp, (ref->num_nbrs + 1) * sizeof(int8_t)); - if (F != NULL && F_res != NULL) { - double scaled_points[PTM_MAX_INPUT_POINTS][3]; + if (F != NULL && F_res != NULL) { + double scaled_points[PTM_MAX_INPUT_POINTS][3]; - ptm::subtract_barycentre(ref->num_nbrs + 1, points, scaled_points); - for (int i = 0; i < ref->num_nbrs + 1; i++) { - scaled_points[i][0] *= res->scale; - scaled_points[i][1] *= res->scale; - scaled_points[i][2] *= res->scale; - } + ptm::subtract_barycentre(ref->num_nbrs + 1, points, scaled_points); + for (int i = 0; i < ref->num_nbrs + 1; i++) { + scaled_points[i][0] *= res->scale; + scaled_points[i][1] *= res->scale; + scaled_points[i][2] *= res->scale; + } - const double (*ref_template)[3] = ref->points; - const double (*ref_penrose)[3] = ref->penrose; - if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) - { - if (ref->template_indices[bi] == 1) - { - ref_template = ref->points_alt1; - ref_penrose = ref->penrose_alt1; - } - else if (ref->template_indices[bi] == 2) - { - ref_template = ref->points_alt2; - ref_penrose = ref->penrose_alt2; - } - else if (ref->template_indices[bi] == 3) - { - ref_template = ref->points_alt3; - ref_penrose = ref->penrose_alt3; - } - } + const double (*ref_template)[3] = ref->points; + const double (*ref_penrose)[3] = ref->penrose; + if (output_conventional_orientation & (ref->type == PTM_MATCH_HCP || ref->type == PTM_MATCH_GRAPHENE || ref->type == PTM_MATCH_DCUB || ref->type == PTM_MATCH_DHEX)) + { + if (ref->template_indices[bi] == 1) + { + ref_template = ref->points_alt1; + ref_penrose = ref->penrose_alt1; + } + else if (ref->template_indices[bi] == 2) + { + ref_template = ref->points_alt2; + ref_penrose = ref->penrose_alt2; + } + else if (ref->template_indices[bi] == 3) + { + ref_template = ref->points_alt3; + ref_penrose = ref->penrose_alt3; + } + } - ptm::calculate_deformation_gradient(ref->num_nbrs + 1, ref_template, - res->mapping, scaled_points, ref_penrose, - F, F_res); - if (ref->type == PTM_MATCH_GRAPHENE) // hack for pseudo-2d structures - F[8] = 1; + ptm::calculate_deformation_gradient(ref->num_nbrs + 1, ref_template, + res->mapping, scaled_points, ref_penrose, + F, F_res); + if (ref->type == PTM_MATCH_GRAPHENE) // hack for pseudo-2d structures + F[8] = 1; - if (P != NULL && U != NULL) - ptm::polar_decomposition_3x3(F, false, U, P); - } + if (P != NULL && U != NULL) + ptm::polar_decomposition_3x3(F, false, U, P); + } - if (output_indices != NULL) - for (int i = 0; i < ref->num_nbrs + 1; i++) - output_indices[i] = ordering[res->mapping[i]]; + if (output_indices != NULL) + for (int i = 0; i < ref->num_nbrs + 1; i++) + output_indices[i] = ordering[res->mapping[i]]; - double interatomic_distance = - calculate_interatomic_distance(ref->type, res->scale); - double lattice_constant = - calculate_lattice_constant(ref->type, interatomic_distance); + double interatomic_distance = + calculate_interatomic_distance(ref->type, res->scale); + double lattice_constant = + calculate_lattice_constant(ref->type, interatomic_distance); - if (p_interatomic_distance != NULL) - *p_interatomic_distance = interatomic_distance; + if (p_interatomic_distance != NULL) + *p_interatomic_distance = interatomic_distance; - if (p_lattice_constant != NULL) - *p_lattice_constant = lattice_constant; + if (p_lattice_constant != NULL) + *p_lattice_constant = lattice_constant; - *p_rmsd = res->rmsd; - *p_scale = res->scale; - memcpy(q, res->q, 4 * sizeof(double)); + *p_rmsd = res->rmsd; + *p_scale = res->scale; + memcpy(q, res->q, 4 * sizeof(double)); } extern bool ptm_initialized; @@ -199,104 +199,104 @@ int ptm_index(ptm_local_handle_t local_handle, size_t atom_index, double *F, double *F_res, double *U, double *P, double *p_interatomic_distance, double *p_lattice_constant, size_t *output_indices) { - assert(ptm_initialized); + assert(ptm_initialized); - int ret = 0; - ptm::result_t res; - res.ref_struct = NULL; - res.rmsd = INFINITY; + int ret = 0; + ptm::result_t res; + res.ref_struct = NULL; + res.rmsd = INFINITY; - size_t ordering[PTM_MAX_INPUT_POINTS]; - int32_t numbers[PTM_MAX_INPUT_POINTS]; - double points[PTM_MAX_INPUT_POINTS][3]; + size_t ordering[PTM_MAX_INPUT_POINTS]; + int32_t numbers[PTM_MAX_INPUT_POINTS]; + double points[PTM_MAX_INPUT_POINTS][3]; - size_t dordering[PTM_MAX_INPUT_POINTS]; - int32_t dnumbers[PTM_MAX_INPUT_POINTS]; - double dpoints[PTM_MAX_INPUT_POINTS][3]; + size_t dordering[PTM_MAX_INPUT_POINTS]; + int32_t dnumbers[PTM_MAX_INPUT_POINTS]; + double dpoints[PTM_MAX_INPUT_POINTS][3]; - size_t gordering[PTM_MAX_INPUT_POINTS]; - int32_t gnumbers[PTM_MAX_INPUT_POINTS]; - double gpoints[PTM_MAX_INPUT_POINTS][3]; + size_t gordering[PTM_MAX_INPUT_POINTS]; + int32_t gnumbers[PTM_MAX_INPUT_POINTS]; + double gpoints[PTM_MAX_INPUT_POINTS][3]; - ptm::convexhull_t ch; - double ch_points[PTM_MAX_INPUT_POINTS][3]; - int num_lpoints = 0; + ptm::convexhull_t ch; + double ch_points[PTM_MAX_INPUT_POINTS][3]; + int num_lpoints = 0; - if (flags & (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | - PTM_CHECK_BCC)) { - int min_points = PTM_NUM_POINTS_SC; - if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) - min_points = PTM_NUM_POINTS_FCC; - if (flags & PTM_CHECK_BCC) - min_points = PTM_NUM_POINTS_BCC; + if (flags & (PTM_CHECK_SC | PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO | + PTM_CHECK_BCC)) { + int min_points = PTM_NUM_POINTS_SC; + if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) + min_points = PTM_NUM_POINTS_FCC; + if (flags & PTM_CHECK_BCC) + min_points = PTM_NUM_POINTS_BCC; - num_lpoints = ptm::calculate_neighbour_ordering( - local_handle, atom_index, min_points, get_neighbours, nbrlist, false, - ordering, points, numbers); - if (num_lpoints >= min_points) { - ptm::normalize_vertices(num_lpoints, points, ch_points); - ch.ok = false; + num_lpoints = ptm::calculate_neighbour_ordering( + local_handle, atom_index, min_points, get_neighbours, nbrlist, false, + ordering, points, numbers); + if (num_lpoints >= min_points) { + ptm::normalize_vertices(num_lpoints, points, ch_points); + ch.ok = false; - if (flags & PTM_CHECK_SC) - ret = match_general(&ptm::structure_sc, ch_points, points, &ch, &res); + if (flags & PTM_CHECK_SC) + ret = match_general(&ptm::structure_sc, ch_points, points, &ch, &res); - if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) - ret = match_fcc_hcp_ico(ch_points, points, flags, &ch, &res); + if (flags & (PTM_CHECK_FCC | PTM_CHECK_HCP | PTM_CHECK_ICO)) + ret = match_fcc_hcp_ico(ch_points, points, flags, &ch, &res); - if (flags & PTM_CHECK_BCC) - ret = match_general(&ptm::structure_bcc, ch_points, points, &ch, &res); - } - } + if (flags & PTM_CHECK_BCC) + ret = match_general(&ptm::structure_bcc, ch_points, points, &ch, &res); + } + } - if (flags & (PTM_CHECK_DCUB | PTM_CHECK_DHEX)) { - const int num_inner = 4, num_outer = 3, max_snbrs = 12; - ret = ptm::calculate_two_shell_neighbour_ordering( - (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, - num_outer, max_snbrs, false, dordering, dpoints, dnumbers); - if (ret == 0) { - ptm::normalize_vertices(PTM_NUM_NBRS_DCUB + 1, dpoints, ch_points); - ch.ok = false; + if (flags & (PTM_CHECK_DCUB | PTM_CHECK_DHEX)) { + const int num_inner = 4, num_outer = 3, max_snbrs = 12; + ret = ptm::calculate_two_shell_neighbour_ordering( + (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, + num_outer, max_snbrs, false, dordering, dpoints, dnumbers); + if (ret == 0) { + ptm::normalize_vertices(PTM_NUM_NBRS_DCUB + 1, dpoints, ch_points); + ch.ok = false; - ret = match_dcub_dhex(ch_points, dpoints, flags, &ch, &res); - } - } + ret = match_dcub_dhex(ch_points, dpoints, flags, &ch, &res); + } + } - if (flags & PTM_CHECK_GRAPHENE) { - const int num_inner = 3, num_outer = 2, max_snbrs = 12; - ret = ptm::calculate_two_shell_neighbour_ordering( - (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, - num_outer, max_snbrs, true, gordering, gpoints, gnumbers); - if (ret == 0) { - ret = match_graphene(gpoints, &res); - } - } + if (flags & PTM_CHECK_GRAPHENE) { + const int num_inner = 3, num_outer = 2, max_snbrs = 12; + ret = ptm::calculate_two_shell_neighbour_ordering( + (void *)local_handle, atom_index, get_neighbours, nbrlist, num_inner, + num_outer, max_snbrs, true, gordering, gpoints, gnumbers); + if (ret == 0) { + ret = match_graphene(gpoints, &res); + } + } - *p_type = PTM_MATCH_NONE; - if (p_alloy_type != NULL) - *p_alloy_type = PTM_ALLOY_NONE; + *p_type = PTM_MATCH_NONE; + if (p_alloy_type != NULL) + *p_alloy_type = PTM_ALLOY_NONE; - if (output_indices != NULL) - memset(output_indices, -1, PTM_MAX_INPUT_POINTS * sizeof(size_t)); + if (output_indices != NULL) + memset(output_indices, -1, PTM_MAX_INPUT_POINTS * sizeof(size_t)); - if (res.ref_struct == NULL) - return PTM_NO_ERROR; + if (res.ref_struct == NULL) + return PTM_NO_ERROR; - if (res.ref_struct->type == PTM_MATCH_DCUB || - res.ref_struct->type == PTM_MATCH_DHEX) { - output_data(&res, dpoints, dnumbers, dordering, - output_conventional_orientation, p_type, p_alloy_type, p_scale, - p_rmsd, q, F, F_res, U, P, p_interatomic_distance, - p_lattice_constant, output_indices); - } else if (res.ref_struct->type == PTM_MATCH_GRAPHENE) { - output_data(&res, gpoints, gnumbers, gordering, - output_conventional_orientation, p_type, p_alloy_type, p_scale, - p_rmsd, q, F, F_res, U, P, p_interatomic_distance, - p_lattice_constant, output_indices); - } else { - output_data(&res, points, numbers, ordering, output_conventional_orientation, - p_type, p_alloy_type, p_scale, p_rmsd, q, F, F_res, U, P, - p_interatomic_distance, p_lattice_constant, output_indices); - } + if (res.ref_struct->type == PTM_MATCH_DCUB || + res.ref_struct->type == PTM_MATCH_DHEX) { + output_data(&res, dpoints, dnumbers, dordering, + output_conventional_orientation, p_type, p_alloy_type, p_scale, + p_rmsd, q, F, F_res, U, P, p_interatomic_distance, + p_lattice_constant, output_indices); + } else if (res.ref_struct->type == PTM_MATCH_GRAPHENE) { + output_data(&res, gpoints, gnumbers, gordering, + output_conventional_orientation, p_type, p_alloy_type, p_scale, + p_rmsd, q, F, F_res, U, P, p_interatomic_distance, + p_lattice_constant, output_indices); + } else { + output_data(&res, points, numbers, ordering, output_conventional_orientation, + p_type, p_alloy_type, p_scale, p_rmsd, q, F, F_res, U, P, + p_interatomic_distance, p_lattice_constant, output_indices); + } - return PTM_NO_ERROR; + return PTM_NO_ERROR; } diff --git a/src/USER-PTM/ptm_initialize_data.cpp b/src/USER-PTM/ptm_initialize_data.cpp index 73a0f16d72..49fbb8a0fe 100644 --- a/src/USER-PTM/ptm_initialize_data.cpp +++ b/src/USER-PTM/ptm_initialize_data.cpp @@ -19,62 +19,62 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI static void make_facets_clockwise(int num_facets, int8_t (*facets)[3], const double (*points)[3]) { - double plane_normal[3]; - double origin[3] = {0, 0, 0}; + double plane_normal[3]; + double origin[3] = {0, 0, 0}; - for (int i = 0;inum_graphs;i++) - { - int8_t code[2 * PTM_MAX_EDGES]; - int8_t degree[PTM_MAX_NBRS]; - int _max_degree = ptm::graph_degree(s->num_facets, s->graphs[i].facets, s->num_nbrs, degree); - assert(_max_degree <= s->max_degree); + for (int i = 0;inum_graphs;i++) + { + int8_t code[2 * PTM_MAX_EDGES]; + int8_t degree[PTM_MAX_NBRS]; + int _max_degree = ptm::graph_degree(s->num_facets, s->graphs[i].facets, s->num_nbrs, degree); + assert(_max_degree <= s->max_degree); - make_facets_clockwise(s->num_facets, s->graphs[i].facets, &s->points[1]); - int ret = ptm::canonical_form_coloured(s->num_facets, s->graphs[i].facets, s->num_nbrs, degree, colours, s->graphs[i].canonical_labelling, (int8_t*)&code[0], &s->graphs[i].hash); - if (ret != 0) - return ret; - } + make_facets_clockwise(s->num_facets, s->graphs[i].facets, &s->points[1]); + int ret = ptm::canonical_form_coloured(s->num_facets, s->graphs[i].facets, s->num_nbrs, degree, colours, s->graphs[i].canonical_labelling, (int8_t*)&code[0], &s->graphs[i].hash); + if (ret != 0) + return ret; + } - return PTM_NO_ERROR; + return PTM_NO_ERROR; } bool ptm_initialized = false; int ptm_initialize_global() { - if (ptm_initialized) - return PTM_NO_ERROR; + if (ptm_initialized) + return PTM_NO_ERROR; - int8_t colours[PTM_MAX_POINTS] = {0}; - int8_t dcolours[PTM_MAX_POINTS] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int8_t colours[PTM_MAX_POINTS] = {0}; + int8_t dcolours[PTM_MAX_POINTS] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int ret = initialize_graphs(&ptm::structure_sc, colours); - ret |= initialize_graphs(&ptm::structure_fcc, colours); - ret |= initialize_graphs(&ptm::structure_hcp, colours); - ret |= initialize_graphs(&ptm::structure_ico, colours); - ret |= initialize_graphs(&ptm::structure_bcc, colours); - ret |= initialize_graphs(&ptm::structure_dcub, dcolours); - ret |= initialize_graphs(&ptm::structure_dhex, dcolours); + int ret = initialize_graphs(&ptm::structure_sc, colours); + ret |= initialize_graphs(&ptm::structure_fcc, colours); + ret |= initialize_graphs(&ptm::structure_hcp, colours); + ret |= initialize_graphs(&ptm::structure_ico, colours); + ret |= initialize_graphs(&ptm::structure_bcc, colours); + ret |= initialize_graphs(&ptm::structure_dcub, dcolours); + ret |= initialize_graphs(&ptm::structure_dhex, dcolours); - if (ret == PTM_NO_ERROR) - ptm_initialized = true; + if (ret == PTM_NO_ERROR) + ptm_initialized = true; - return ret; + return ret; } ptm_local_handle_t ptm_initialize_local() { - assert(ptm_initialized); - return (ptm_local_handle_t)ptm::voronoi_initialize_local(); + assert(ptm_initialized); + return (ptm_local_handle_t)ptm::voronoi_initialize_local(); } void ptm_uninitialize_local(ptm_local_handle_t ptr) { - ptm::voronoi_uninitialize_local(ptr); + ptm::voronoi_uninitialize_local(ptr); } diff --git a/src/USER-PTM/ptm_initialize_data.h b/src/USER-PTM/ptm_initialize_data.h index 47b7aa4f20..20c9921962 100644 --- a/src/USER-PTM/ptm_initialize_data.h +++ b/src/USER-PTM/ptm_initialize_data.h @@ -25,186 +25,186 @@ namespace ptm { typedef struct { - int type; - int num_nbrs; - int num_facets; - int max_degree; - int num_graphs; - graph_t* graphs; - const double (*points)[3]; - const double (*points_alt1)[3]; - const double (*points_alt2)[3]; - const double (*points_alt3)[3]; - const double (*penrose)[3]; - const double (*penrose_alt1)[3]; - const double (*penrose_alt2)[3]; - const double (*penrose_alt3)[3]; - int num_mappings; - const int8_t (*mapping)[PTM_MAX_POINTS]; - const int8_t (*mapping_conventional)[PTM_MAX_POINTS]; - const int8_t *template_indices; + int type; + int num_nbrs; + int num_facets; + int max_degree; + int num_graphs; + graph_t* graphs; + const double (*points)[3]; + const double (*points_alt1)[3]; + const double (*points_alt2)[3]; + const double (*points_alt3)[3]; + const double (*penrose)[3]; + const double (*penrose_alt1)[3]; + const double (*penrose_alt2)[3]; + const double (*penrose_alt3)[3]; + int num_mappings; + const int8_t (*mapping)[PTM_MAX_POINTS]; + const int8_t (*mapping_conventional)[PTM_MAX_POINTS]; + const int8_t *template_indices; } refdata_t; -const refdata_t structure_sc = { PTM_MATCH_SC, //.type - 6, //.num_nbrs - 8, //.num_facets - 4, //.max_degree - NUM_SC_GRAPHS, //.num_graphs - graphs_sc, //.graphs - ptm_template_sc, //.points - NULL, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_sc, //.penrose - NULL, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_CUBIC_MAPPINGS, //.num_mappings - mapping_sc, //.mapping - NULL, //.mapping_conventional - NULL, //.template_indices - }; +const refdata_t structure_sc = { PTM_MATCH_SC, //.type + 6, //.num_nbrs + 8, //.num_facets + 4, //.max_degree + NUM_SC_GRAPHS, //.num_graphs + graphs_sc, //.graphs + ptm_template_sc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_sc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_sc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; -const refdata_t structure_fcc = { PTM_MATCH_FCC, //.type - 12, //.num_nbrs - 20, //.num_facets - 6, //.max_degree - NUM_FCC_GRAPHS, //.num_graphs - graphs_fcc, //.graphs - ptm_template_fcc, //.points - NULL, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_fcc, //.penrose - NULL, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_CUBIC_MAPPINGS, //.num_mappings - mapping_fcc, //.mapping - NULL, //.mapping_conventional - NULL, //.template_indices - }; +const refdata_t structure_fcc = { PTM_MATCH_FCC, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_FCC_GRAPHS, //.num_graphs + graphs_fcc, //.graphs + ptm_template_fcc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_fcc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_fcc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; -const refdata_t structure_hcp = { PTM_MATCH_HCP, //.type - 12, //.num_nbrs - 20, //.num_facets - 6, //.max_degree - NUM_HCP_GRAPHS, //.num_graphs - graphs_hcp, //.graphs - ptm_template_hcp, //.points - ptm_template_hcp_alt1, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_hcp, //.penrose - penrose_hcp_alt1, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_HEX_MAPPINGS, //.num_mappings - mapping_hcp, //.mapping - mapping_hcp_conventional, //.mapping_conventional - template_indices_hcp, //.template_indices - }; +const refdata_t structure_hcp = { PTM_MATCH_HCP, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_HCP_GRAPHS, //.num_graphs + graphs_hcp, //.graphs + ptm_template_hcp, //.points + ptm_template_hcp_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_hcp, //.penrose + penrose_hcp_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_HEX_MAPPINGS, //.num_mappings + mapping_hcp, //.mapping + mapping_hcp_conventional, //.mapping_conventional + template_indices_hcp, //.template_indices + }; -const refdata_t structure_ico = { PTM_MATCH_ICO, //.type - 12, //.num_nbrs - 20, //.num_facets - 6, //.max_degree - NUM_ICO_GRAPHS, //.num_graphs - graphs_ico, //.graphs - ptm_template_ico, //.points - NULL, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_ico, //.penrose - NULL, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_ICO_MAPPINGS, //.num_mappings - mapping_ico, //.mapping - NULL, //.mapping_conventional - NULL, //.template_indices - }; +const refdata_t structure_ico = { PTM_MATCH_ICO, //.type + 12, //.num_nbrs + 20, //.num_facets + 6, //.max_degree + NUM_ICO_GRAPHS, //.num_graphs + graphs_ico, //.graphs + ptm_template_ico, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_ico, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_ICO_MAPPINGS, //.num_mappings + mapping_ico, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; -const refdata_t structure_bcc = { PTM_MATCH_BCC, //.type - 14, //.num_nbrs - 24, //.num_facets - 8, //.max_degree - NUM_BCC_GRAPHS, //.num_graphs - graphs_bcc, //.graphs - ptm_template_bcc, //.points - NULL, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_bcc, //.penrose - NULL, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_CUBIC_MAPPINGS, //.num_mappings - mapping_bcc, //.mapping - NULL, //.mapping_conventional - NULL, //.template_indices - }; +const refdata_t structure_bcc = { PTM_MATCH_BCC, //.type + 14, //.num_nbrs + 24, //.num_facets + 8, //.max_degree + NUM_BCC_GRAPHS, //.num_graphs + graphs_bcc, //.graphs + ptm_template_bcc, //.points + NULL, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_bcc, //.penrose + NULL, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_CUBIC_MAPPINGS, //.num_mappings + mapping_bcc, //.mapping + NULL, //.mapping_conventional + NULL, //.template_indices + }; -const refdata_t structure_dcub = { PTM_MATCH_DCUB, //.type - 16, //.num_nbrs - 28, //.num_facets - 8, //.max_degree - NUM_DCUB_GRAPHS, //.num_graphs - graphs_dcub, //.graphs - ptm_template_dcub, //.points - ptm_template_dcub_alt1, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_dcub, //.penrose - penrose_dcub_alt1, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - NUM_DCUB_MAPPINGS, //.num_mappings - mapping_dcub, //.mapping - mapping_dcub_conventional, //.mapping_conventional - template_indices_dcub, //.template_indices - }; +const refdata_t structure_dcub = { PTM_MATCH_DCUB, //.type + 16, //.num_nbrs + 28, //.num_facets + 8, //.max_degree + NUM_DCUB_GRAPHS, //.num_graphs + graphs_dcub, //.graphs + ptm_template_dcub, //.points + ptm_template_dcub_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_dcub, //.penrose + penrose_dcub_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + NUM_DCUB_MAPPINGS, //.num_mappings + mapping_dcub, //.mapping + mapping_dcub_conventional, //.mapping_conventional + template_indices_dcub, //.template_indices + }; -const refdata_t structure_dhex = { PTM_MATCH_DHEX, //.type - 16, //.num_nbrs - 28, //.num_facets - 8, //.max_degree - NUM_DHEX_GRAPHS, //.num_graphs - graphs_dhex, //.graphs - ptm_template_dhex, //.points - ptm_template_dhex_alt1, //.points_alt1 - ptm_template_dhex_alt2, //.points_alt2 - ptm_template_dhex_alt3, //.points_alt3 - penrose_dhex, //.penrose - penrose_dhex_alt1, //.penrose_alt1 - penrose_dhex_alt2, //.penrose_alt2 - penrose_dhex_alt3, //.penrose_alt3 - NUM_DHEX_MAPPINGS, //.num_mappings - mapping_dhex, //.mapping - mapping_dhex_conventional, //.mapping_conventional - template_indices_dhex, //.template_indices - }; +const refdata_t structure_dhex = { PTM_MATCH_DHEX, //.type + 16, //.num_nbrs + 28, //.num_facets + 8, //.max_degree + NUM_DHEX_GRAPHS, //.num_graphs + graphs_dhex, //.graphs + ptm_template_dhex, //.points + ptm_template_dhex_alt1, //.points_alt1 + ptm_template_dhex_alt2, //.points_alt2 + ptm_template_dhex_alt3, //.points_alt3 + penrose_dhex, //.penrose + penrose_dhex_alt1, //.penrose_alt1 + penrose_dhex_alt2, //.penrose_alt2 + penrose_dhex_alt3, //.penrose_alt3 + NUM_DHEX_MAPPINGS, //.num_mappings + mapping_dhex, //.mapping + mapping_dhex_conventional, //.mapping_conventional + template_indices_dhex, //.template_indices + }; -const refdata_t structure_graphene = { PTM_MATCH_GRAPHENE, //.type - 9, //.num_nbrs - -1, //.num_facets - -1, //.max_degree - -1, //.num_graphs - NULL, //.graphs - ptm_template_graphene, //.points - ptm_template_graphene_alt1, //.points_alt1 - NULL, //.points_alt2 - NULL, //.points_alt3 - penrose_graphene, //.penrose - penrose_graphene_alt1, //.penrose_alt1 - NULL, //.penrose_alt2 - NULL, //.penrose_alt3 - -1, //.num_mappings - mapping_graphene, //.mapping - mapping_graphene_conventional, //.mapping_conventional - template_indices_graphene, //.template_indices - }; +const refdata_t structure_graphene = { PTM_MATCH_GRAPHENE, //.type + 9, //.num_nbrs + -1, //.num_facets + -1, //.max_degree + -1, //.num_graphs + NULL, //.graphs + ptm_template_graphene, //.points + ptm_template_graphene_alt1, //.points_alt1 + NULL, //.points_alt2 + NULL, //.points_alt3 + penrose_graphene, //.penrose + penrose_graphene_alt1, //.penrose_alt1 + NULL, //.penrose_alt2 + NULL, //.penrose_alt3 + -1, //.num_mappings + mapping_graphene, //.mapping + mapping_graphene_conventional, //.mapping_conventional + template_indices_graphene, //.template_indices + }; } #ifdef __cplusplus diff --git a/src/USER-PTM/ptm_neighbour_ordering.cpp b/src/USER-PTM/ptm_neighbour_ordering.cpp index 621ef2565f..cb72a43711 100644 --- a/src/USER-PTM/ptm_neighbour_ordering.cpp +++ b/src/USER-PTM/ptm_neighbour_ordering.cpp @@ -25,375 +25,375 @@ namespace ptm { typedef struct { - double area; - double dist; - int index; - int inner; - int32_t number; - double offset[3]; + double area; + double dist; + int index; + int inner; + int32_t number; + double offset[3]; } sorthelper_t; typedef struct { - size_t index; - int32_t number; - double area; - double offset[3]; + size_t index; + int32_t number; + double area; + double offset[3]; } solidnbr_t; static bool sorthelper_compare(sorthelper_t const& a, sorthelper_t const& b) { - if (a.area > b.area) - return true; + if (a.area > b.area) + return true; - if (a.area < b.area) - return false; + if (a.area < b.area) + return false; - if (a.dist < b.dist) - return true; + if (a.dist < b.dist) + return true; - return false; + return false; } static double dot_product(double* a, double* b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } static void cross_product(double* a, double* b, double* c) { - c[0] = a[1] * b[2] - a[2] * b[1]; - c[1] = a[2] * b[0] - a[0] * b[2]; - c[2] = a[0] * b[1] - a[1] * b[0]; + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; } -static double calculate_solid_angle(double* R1, double* R2, double* R3) //norms of R1-R3 must be 1 +static double calculate_solid_angle(double* R1, double* R2, double* R3) //norms of R1-R3 must be 1 { - double R2R3[3]; - cross_product(R2, R3, R2R3); - double numerator = dot_product(R1, R2R3); + double R2R3[3]; + cross_product(R2, R3, R2R3); + double numerator = dot_product(R1, R2R3); - double r1r2 = dot_product(R1, R2); - double r2r3 = dot_product(R2, R3); - double r3r1 = dot_product(R3, R1); + double r1r2 = dot_product(R1, R2); + double r2r3 = dot_product(R2, R3); + double r3r1 = dot_product(R3, R1); - double denominator = 1 + r1r2 + r3r1 + r2r3; - return fabs(2 * atan2(numerator, denominator)); + double denominator = 1 + r1r2 + r3r1 + r2r3; + return fabs(2 * atan2(numerator, denominator)); } //todo: change voronoi code to return errors rather than exiting static int calculate_voronoi_face_areas(int num_points, const double (*_points)[3], double* normsq, double max_norm, ptm_voro::voronoicell_neighbor* v, bool calc_solid_angles, - std::vector& nbr_indices, std::vector& face_areas) + std::vector& nbr_indices, std::vector& face_areas) { - const double k = 10 * max_norm; - v->init(-k,k,-k,k,-k,k); + const double k = 10 * max_norm; + v->init(-k,k,-k,k,-k,k); - for (int i=1;inplane(x,y,z,normsq[i],i); - } + for (int i=1;inplane(x,y,z,normsq[i],i); + } - v->neighbors(nbr_indices); + v->neighbors(nbr_indices); //v->face_areas(face_areas); - if (!calc_solid_angles) - { - v->face_areas(face_areas); - return 0; - } - else - { - std::vector face_vertices; - std::vector vertices; + if (!calc_solid_angles) + { + v->face_areas(face_areas); + return 0; + } + else + { + std::vector face_vertices; + std::vector vertices; - v->face_vertices(face_vertices); - v->vertices(0, 0, 0, vertices); + v->face_vertices(face_vertices); + v->vertices(0, 0, 0, vertices); - size_t num_vertices = vertices.size() / 3; - for (size_t i=0;inumber_of_faces(); + int num_faces = v->number_of_faces(); #ifdef DEBUG - printf("number of voronoi faces: %d\n", num_faces); + printf("number of voronoi faces: %d\n", num_faces); #endif //std::vector solids(face_areas.size()+1); - size_t c = 0; - for (int current_face=0;current_face 0) - { - double solid_angle = 0; - int u = face_vertices[c]; - int v = face_vertices[c+1]; - for (int i=2;i 0) + { + double solid_angle = 0; + int u = face_vertices[c]; + int v = face_vertices[c+1]; + for (int i=2;i nbr_indices(num_points + 6); - std::vector face_areas(num_points + 6); - int ret = calculate_voronoi_face_areas(num_points, points, normsq, max_norm, voronoi_handle, calc_solid_angles, nbr_indices, face_areas); - if (ret != 0) - return ret; + std::vector nbr_indices(num_points + 6); + std::vector face_areas(num_points + 6); + int ret = calculate_voronoi_face_areas(num_points, points, normsq, max_norm, voronoi_handle, calc_solid_angles, nbr_indices, face_areas); + if (ret != 0) + return ret; - double areas[PTM_MAX_INPUT_POINTS]; - memset(areas, 0, num_points * sizeof(double)); - areas[0] = INFINITY; - for (size_t i=0;i 0) - areas[index] = face_areas[i]; - } + double areas[PTM_MAX_INPUT_POINTS]; + memset(areas, 0, num_points * sizeof(double)); + areas[0] = INFINITY; + for (size_t i=0;i 0) + areas[index] = face_areas[i]; + } - for (int i=0;i claimed; - claimed.insert(atom_index); - for (int i=0;i claimed; + claimed.insert(atom_index); + for (int i=0;i= num_outer || already_claimed) - continue; + bool already_claimed = claimed.find(nbr_atom_index) != claimed.end(); + if (counts[inner] >= num_outer || already_claimed) + continue; - nbr_indices[1 + num_inner + num_outer * inner + counts[inner]] = nbr_atom_index; - numbers[1 + num_inner + num_outer * inner + counts[inner]] = data[i].number; - memcpy(points[1 + num_inner + num_outer * inner + counts[inner]], &data[i].offset, 3 * sizeof(double)); - claimed.insert(nbr_atom_index); + nbr_indices[1 + num_inner + num_outer * inner + counts[inner]] = nbr_atom_index; + numbers[1 + num_inner + num_outer * inner + counts[inner]] = data[i].number; + memcpy(points[1 + num_inner + num_outer * inner + counts[inner]], &data[i].offset, 3 * sizeof(double)); + claimed.insert(nbr_atom_index); - counts[inner]++; - num_found++; - if (num_found >= num_inner * num_outer) - break; - } + counts[inner]++; + num_found++; + if (num_found >= num_inner * num_outer) + break; + } - if (num_found != num_inner * num_outer) - return -1; + if (num_found != num_inner * num_outer) + return -1; - return 0; + return 0; } } diff --git a/src/USER-PTM/ptm_neighbour_ordering.h b/src/USER-PTM/ptm_neighbour_ordering.h index 038d6c400b..4a4fb8ce8b 100644 --- a/src/USER-PTM/ptm_neighbour_ordering.h +++ b/src/USER-PTM/ptm_neighbour_ordering.h @@ -14,13 +14,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace ptm { -int calculate_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int min_points, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, - double (*nbr_pos)[3]), void* nbrlist, bool calc_solid_angles, - size_t* nbr_indices, double (*points)[3], int32_t* numbers); +int calculate_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int min_points, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, + double (*nbr_pos)[3]), void* nbrlist, bool calc_solid_angles, + size_t* nbr_indices, double (*points)[3], int32_t* numbers); -int calculate_two_shell_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, double (*nbr_pos)[3]), void* nbrlist, - int num_inner, int num_outer, int max_snbrs, bool calc_solid_angles, - size_t* nbr_indices, double (*points)[3], int32_t* numbers); +int calculate_two_shell_neighbour_ordering( void* _voronoi_handle, size_t atom_index, int (get_neighbours)(void* vdata, size_t central_index, size_t atom_index, int num, size_t* nbr_indices, int32_t* numbers, double (*nbr_pos)[3]), void* nbrlist, + int num_inner, int num_outer, int max_snbrs, bool calc_solid_angles, + size_t* nbr_indices, double (*points)[3], int32_t* numbers); void* voronoi_initialize_local(); void voronoi_uninitialize_local(void* ptr); diff --git a/src/USER-PTM/ptm_normalize_vertices.cpp b/src/USER-PTM/ptm_normalize_vertices.cpp index 3d35fbce43..8817e9faaf 100644 --- a/src/USER-PTM/ptm_normalize_vertices.cpp +++ b/src/USER-PTM/ptm_normalize_vertices.cpp @@ -13,54 +13,54 @@ namespace ptm { void subtract_barycentre(int num, double (*points)[3], double (*normalized)[3]) { - //calculate barycentre - double sum[3] = {0, 0, 0}; - for (int i=0;i nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written - * permission. + * endorse or promote products derived from this software without specific prior written + * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -65,23 +65,23 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Source: started anew. + * Source: started anew. * * Change History: - * 2009/04/13 Started source - * 2010/03/28 Modified FastCalcRMSDAndRotation() to handle tiny qsqr - * If trying all rows of the adjoint still gives too small - * qsqr, then just return identity matrix. (DLT) - * 2010/06/30 Fixed prob in assigning A[9] = 0 in InnerProduct() - * invalid mem access - * 2011/02/21 Made CenterCoords use weights - * 2011/05/02 Finally changed CenterCoords declaration in qcprot.h - * Also changed some functions to static - * 2011/07/08 put in fabs() to fix taking sqrt of small neg numbers, fp error - * 2012/07/26 minor changes to comments and main.c, more info (v.1.4) + * 2009/04/13 Started source + * 2010/03/28 Modified FastCalcRMSDAndRotation() to handle tiny qsqr + * If trying all rows of the adjoint still gives too small + * qsqr, then just return identity matrix. (DLT) + * 2010/06/30 Fixed prob in assigning A[9] = 0 in InnerProduct() + * invalid mem access + * 2011/02/21 Made CenterCoords use weights + * 2011/05/02 Finally changed CenterCoords declaration in qcprot.h + * Also changed some functions to static + * 2011/07/08 put in fabs() to fix taking sqrt of small neg numbers, fp error + * 2012/07/26 minor changes to comments and main.c, more info (v.1.4) * * 2016/05/29 QCP method adapted for polar decomposition of a 3x3 matrix, - * for use in Polyhedral Template Matching. + * for use in Polyhedral Template Matching. * ******************************************************************************/ @@ -95,246 +95,246 @@ namespace ptm { static void matmul_3x3(double* A, double* x, double* b) { - b[0] = A[0] * x[0] + A[1] * x[3] + A[2] * x[6]; - b[3] = A[3] * x[0] + A[4] * x[3] + A[5] * x[6]; - b[6] = A[6] * x[0] + A[7] * x[3] + A[8] * x[6]; + b[0] = A[0] * x[0] + A[1] * x[3] + A[2] * x[6]; + b[3] = A[3] * x[0] + A[4] * x[3] + A[5] * x[6]; + b[6] = A[6] * x[0] + A[7] * x[3] + A[8] * x[6]; - b[1] = A[0] * x[1] + A[1] * x[4] + A[2] * x[7]; - b[4] = A[3] * x[1] + A[4] * x[4] + A[5] * x[7]; - b[7] = A[6] * x[1] + A[7] * x[4] + A[8] * x[7]; + b[1] = A[0] * x[1] + A[1] * x[4] + A[2] * x[7]; + b[4] = A[3] * x[1] + A[4] * x[4] + A[5] * x[7]; + b[7] = A[6] * x[1] + A[7] * x[4] + A[8] * x[7]; - b[2] = A[0] * x[2] + A[1] * x[5] + A[2] * x[8]; - b[5] = A[3] * x[2] + A[4] * x[5] + A[5] * x[8]; - b[8] = A[6] * x[2] + A[7] * x[5] + A[8] * x[8]; + b[2] = A[0] * x[2] + A[1] * x[5] + A[2] * x[8]; + b[5] = A[3] * x[2] + A[4] * x[5] + A[5] * x[8]; + b[8] = A[6] * x[2] + A[7] * x[5] + A[8] * x[8]; } static double matrix_determinant_3x3(double* A) { - return A[0] * (A[4]*A[8] - A[5]*A[7]) - - A[1] * (A[3]*A[8] - A[5]*A[6]) - + A[2] * (A[3]*A[7] - A[4]*A[6]); + return A[0] * (A[4]*A[8] - A[5]*A[7]) + - A[1] * (A[3]*A[8] - A[5]*A[6]) + + A[2] * (A[3]*A[7] - A[4]*A[6]); } static void flip_matrix(double* A) { - for (int i=0;i<9;i++) - A[i] = -A[i]; + for (int i=0;i<9;i++) + A[i] = -A[i]; } static bool optimal_quaternion(double* A, bool polar, double E0, double* p_nrmsdsq, double* qopt) { - const double evecprec = 1e-6; - const double evalprec = 1e-11; + const double evecprec = 1e-6; + const double evalprec = 1e-11; - double Sxx = A[0], Sxy = A[1], Sxz = A[2], - Syx = A[3], Syy = A[4], Syz = A[5], - Szx = A[6], Szy = A[7], Szz = A[8]; + double Sxx = A[0], Sxy = A[1], Sxz = A[2], + Syx = A[3], Syy = A[4], Syz = A[5], + Szx = A[6], Szy = A[7], Szz = A[8]; - double Sxx2 = Sxx * Sxx, Syy2 = Syy * Syy, Szz2 = Szz * Szz, - Sxy2 = Sxy * Sxy, Syz2 = Syz * Syz, Sxz2 = Sxz * Sxz, - Syx2 = Syx * Syx, Szy2 = Szy * Szy, Szx2 = Szx * Szx; + double Sxx2 = Sxx * Sxx, Syy2 = Syy * Syy, Szz2 = Szz * Szz, + Sxy2 = Sxy * Sxy, Syz2 = Syz * Syz, Sxz2 = Sxz * Sxz, + Syx2 = Syx * Syx, Szy2 = Szy * Szy, Szx2 = Szx * Szx; - double fnorm_squared = Sxx2 + Syy2 + Szz2 + Sxy2 + Syz2 + Sxz2 + Syx2 + Szy2 + Szx2; + double fnorm_squared = Sxx2 + Syy2 + Szz2 + Sxy2 + Syz2 + Sxz2 + Syx2 + Szy2 + Szx2; - double SyzSzymSyySzz2 = 2.0 * (Syz * Szy - Syy * Szz); - double Sxx2Syy2Szz2Syz2Szy2 = Syy2 + Szz2 - Sxx2 + Syz2 + Szy2; - double SxzpSzx = Sxz + Szx; - double SyzpSzy = Syz + Szy; - double SxypSyx = Sxy + Syx; - double SyzmSzy = Syz - Szy; - double SxzmSzx = Sxz - Szx; - double SxymSyx = Sxy - Syx; - double SxxpSyy = Sxx + Syy; - double SxxmSyy = Sxx - Syy; - double Sxy2Sxz2Syx2Szx2 = Sxy2 + Sxz2 - Syx2 - Szx2; + double SyzSzymSyySzz2 = 2.0 * (Syz * Szy - Syy * Szz); + double Sxx2Syy2Szz2Syz2Szy2 = Syy2 + Szz2 - Sxx2 + Syz2 + Szy2; + double SxzpSzx = Sxz + Szx; + double SyzpSzy = Syz + Szy; + double SxypSyx = Sxy + Syx; + double SyzmSzy = Syz - Szy; + double SxzmSzx = Sxz - Szx; + double SxymSyx = Sxy - Syx; + double SxxpSyy = Sxx + Syy; + double SxxmSyy = Sxx - Syy; + double Sxy2Sxz2Syx2Szx2 = Sxy2 + Sxz2 - Syx2 - Szx2; - double C[3]; - C[0] = Sxy2Sxz2Syx2Szx2 * Sxy2Sxz2Syx2Szx2 - + (Sxx2Syy2Szz2Syz2Szy2 + SyzSzymSyySzz2) * (Sxx2Syy2Szz2Syz2Szy2 - SyzSzymSyySzz2) - + (-(SxzpSzx)*(SyzmSzy)+(SxymSyx)*(SxxmSyy-Szz)) * (-(SxzmSzx)*(SyzpSzy)+(SxymSyx)*(SxxmSyy+Szz)) - + (-(SxzpSzx)*(SyzpSzy)-(SxypSyx)*(SxxpSyy-Szz)) * (-(SxzmSzx)*(SyzmSzy)-(SxypSyx)*(SxxpSyy+Szz)) - + (+(SxypSyx)*(SyzpSzy)+(SxzpSzx)*(SxxmSyy+Szz)) * (-(SxymSyx)*(SyzmSzy)+(SxzpSzx)*(SxxpSyy+Szz)) - + (+(SxypSyx)*(SyzmSzy)+(SxzmSzx)*(SxxmSyy-Szz)) * (-(SxymSyx)*(SyzpSzy)+(SxzmSzx)*(SxxpSyy-Szz)); + double C[3]; + C[0] = Sxy2Sxz2Syx2Szx2 * Sxy2Sxz2Syx2Szx2 + + (Sxx2Syy2Szz2Syz2Szy2 + SyzSzymSyySzz2) * (Sxx2Syy2Szz2Syz2Szy2 - SyzSzymSyySzz2) + + (-(SxzpSzx)*(SyzmSzy)+(SxymSyx)*(SxxmSyy-Szz)) * (-(SxzmSzx)*(SyzpSzy)+(SxymSyx)*(SxxmSyy+Szz)) + + (-(SxzpSzx)*(SyzpSzy)-(SxypSyx)*(SxxpSyy-Szz)) * (-(SxzmSzx)*(SyzmSzy)-(SxypSyx)*(SxxpSyy+Szz)) + + (+(SxypSyx)*(SyzpSzy)+(SxzpSzx)*(SxxmSyy+Szz)) * (-(SxymSyx)*(SyzmSzy)+(SxzpSzx)*(SxxpSyy+Szz)) + + (+(SxypSyx)*(SyzmSzy)+(SxzmSzx)*(SxxmSyy-Szz)) * (-(SxymSyx)*(SyzpSzy)+(SxzmSzx)*(SxxpSyy-Szz)); - C[1] = 8.0 * (Sxx*Syz*Szy + Syy*Szx*Sxz + Szz*Sxy*Syx - Sxx*Syy*Szz - Syz*Szx*Sxy - Szy*Syx*Sxz); - C[2] = -2.0 * fnorm_squared; + C[1] = 8.0 * (Sxx*Syz*Szy + Syy*Szx*Sxz + Szz*Sxy*Syx - Sxx*Syy*Szz - Syz*Szx*Sxy - Szy*Syx*Sxz); + C[2] = -2.0 * fnorm_squared; - //Newton-Raphson - double mxEigenV = polar ? sqrt(3 * fnorm_squared) : E0; - if (mxEigenV > evalprec) - { - for (int i=0;i<50;i++) - { - double oldg = mxEigenV; - double x2 = mxEigenV*mxEigenV; - double b = (x2 + C[2])*mxEigenV; - double a = b + C[1]; - double delta = ((a * mxEigenV + C[0]) / (2 * x2 * mxEigenV + b + a)); - mxEigenV -= delta; - if (fabs(mxEigenV - oldg) < fabs(evalprec * mxEigenV)) - break; - } - } - else - { - mxEigenV = 0.0; - } + //Newton-Raphson + double mxEigenV = polar ? sqrt(3 * fnorm_squared) : E0; + if (mxEigenV > evalprec) + { + for (int i=0;i<50;i++) + { + double oldg = mxEigenV; + double x2 = mxEigenV*mxEigenV; + double b = (x2 + C[2])*mxEigenV; + double a = b + C[1]; + double delta = ((a * mxEigenV + C[0]) / (2 * x2 * mxEigenV + b + a)); + mxEigenV -= delta; + if (fabs(mxEigenV - oldg) < fabs(evalprec * mxEigenV)) + break; + } + } + else + { + mxEigenV = 0.0; + } - (*p_nrmsdsq) = std::max(0.0, 2.0 * (E0 - mxEigenV)); + (*p_nrmsdsq) = std::max(0.0, 2.0 * (E0 - mxEigenV)); - double a11 = SxxpSyy + Szz - mxEigenV; - double a12 = SyzmSzy; - double a13 = -SxzmSzx; - double a14 = SxymSyx; + double a11 = SxxpSyy + Szz - mxEigenV; + double a12 = SyzmSzy; + double a13 = -SxzmSzx; + double a14 = SxymSyx; - double a21 = SyzmSzy; - double a22 = SxxmSyy - Szz -mxEigenV; - double a23 = SxypSyx; - double a24 = SxzpSzx; + double a21 = SyzmSzy; + double a22 = SxxmSyy - Szz -mxEigenV; + double a23 = SxypSyx; + double a24 = SxzpSzx; - double a31 = a13; - double a32 = a23; - double a33 = Syy - Sxx - Szz - mxEigenV; - double a34 = SyzpSzy; + double a31 = a13; + double a32 = a23; + double a33 = Syy - Sxx - Szz - mxEigenV; + double a34 = SyzpSzy; - double a41 = a14; - double a42 = a24; - double a43 = a34; - double a44 = Szz - SxxpSyy - mxEigenV; + double a41 = a14; + double a42 = a24; + double a43 = a34; + double a44 = Szz - SxxpSyy - mxEigenV; - double a3344_4334 = a33 * a44 - a43 * a34; - double a3244_4234 = a32 * a44 - a42 * a34; - double a3243_4233 = a32 * a43 - a42 * a33; - double a3143_4133 = a31 * a43 - a41 * a33; - double a3144_4134 = a31 * a44 - a41 * a34; - double a3142_4132 = a31 * a42 - a41 * a32; - double a1324_1423 = a13 * a24 - a14 * a23; - double a1224_1422 = a12 * a24 - a14 * a22; - double a1223_1322 = a12 * a23 - a13 * a22; - double a1124_1421 = a11 * a24 - a14 * a21; - double a1123_1321 = a11 * a23 - a13 * a21; - double a1122_1221 = a11 * a22 - a12 * a21; + double a3344_4334 = a33 * a44 - a43 * a34; + double a3244_4234 = a32 * a44 - a42 * a34; + double a3243_4233 = a32 * a43 - a42 * a33; + double a3143_4133 = a31 * a43 - a41 * a33; + double a3144_4134 = a31 * a44 - a41 * a34; + double a3142_4132 = a31 * a42 - a41 * a32; + double a1324_1423 = a13 * a24 - a14 * a23; + double a1224_1422 = a12 * a24 - a14 * a22; + double a1223_1322 = a12 * a23 - a13 * a22; + double a1124_1421 = a11 * a24 - a14 * a21; + double a1123_1321 = a11 * a23 - a13 * a21; + double a1122_1221 = a11 * a22 - a12 * a21; - double q[4][4]; - q[0][0] = a12 * a3344_4334 - a13 * a3244_4234 + a14 * a3243_4233; - q[0][1] = -a11 * a3344_4334 + a13 * a3144_4134 - a14 * a3143_4133; - q[0][2] = a11 * a3244_4234 - a12 * a3144_4134 + a14 * a3142_4132; - q[0][3] = -a11 * a3243_4233 + a12 * a3143_4133 - a13 * a3142_4132; + double q[4][4]; + q[0][0] = a12 * a3344_4334 - a13 * a3244_4234 + a14 * a3243_4233; + q[0][1] = -a11 * a3344_4334 + a13 * a3144_4134 - a14 * a3143_4133; + q[0][2] = a11 * a3244_4234 - a12 * a3144_4134 + a14 * a3142_4132; + q[0][3] = -a11 * a3243_4233 + a12 * a3143_4133 - a13 * a3142_4132; - q[1][0] = a22 * a3344_4334 - a23 * a3244_4234 + a24 * a3243_4233; - q[1][1] = -a21 * a3344_4334 + a23 * a3144_4134 - a24 * a3143_4133; - q[1][2] = a21 * a3244_4234 - a22 * a3144_4134 + a24 * a3142_4132; - q[1][3] = -a21 * a3243_4233 + a22 * a3143_4133 - a23 * a3142_4132; + q[1][0] = a22 * a3344_4334 - a23 * a3244_4234 + a24 * a3243_4233; + q[1][1] = -a21 * a3344_4334 + a23 * a3144_4134 - a24 * a3143_4133; + q[1][2] = a21 * a3244_4234 - a22 * a3144_4134 + a24 * a3142_4132; + q[1][3] = -a21 * a3243_4233 + a22 * a3143_4133 - a23 * a3142_4132; - q[2][0] = a32 * a1324_1423 - a33 * a1224_1422 + a34 * a1223_1322; - q[2][1] = -a31 * a1324_1423 + a33 * a1124_1421 - a34 * a1123_1321; - q[2][2] = a31 * a1224_1422 - a32 * a1124_1421 + a34 * a1122_1221; - q[2][3] = -a31 * a1223_1322 + a32 * a1123_1321 - a33 * a1122_1221; + q[2][0] = a32 * a1324_1423 - a33 * a1224_1422 + a34 * a1223_1322; + q[2][1] = -a31 * a1324_1423 + a33 * a1124_1421 - a34 * a1123_1321; + q[2][2] = a31 * a1224_1422 - a32 * a1124_1421 + a34 * a1122_1221; + q[2][3] = -a31 * a1223_1322 + a32 * a1123_1321 - a33 * a1122_1221; - q[3][0] = a42 * a1324_1423 - a43 * a1224_1422 + a44 * a1223_1322; - q[3][1] = -a41 * a1324_1423 + a43 * a1124_1421 - a44 * a1123_1321; - q[3][2] = a41 * a1224_1422 - a42 * a1124_1421 + a44 * a1122_1221; - q[3][3] = -a41 * a1223_1322 + a42 * a1123_1321 - a43 * a1122_1221; + q[3][0] = a42 * a1324_1423 - a43 * a1224_1422 + a44 * a1223_1322; + q[3][1] = -a41 * a1324_1423 + a43 * a1124_1421 - a44 * a1123_1321; + q[3][2] = a41 * a1224_1422 - a42 * a1124_1421 + a44 * a1122_1221; + q[3][3] = -a41 * a1223_1322 + a42 * a1123_1321 - a43 * a1122_1221; - double qsqr[4]; - for (int i=0;i<4;i++) - qsqr[i] = q[i][0]*q[i][0] + q[i][1]*q[i][1] + q[i][2]*q[i][2] + q[i][3]*q[i][3]; + double qsqr[4]; + for (int i=0;i<4;i++) + qsqr[i] = q[i][0]*q[i][0] + q[i][1]*q[i][1] + q[i][2]*q[i][2] + q[i][3]*q[i][3]; - int bi = 0; - double max = 0; - for (int i=0;i<4;i++) - { - if (qsqr[i] > max) - { - bi = i; - max = qsqr[i]; - } - } + int bi = 0; + double max = 0; + for (int i=0;i<4;i++) + { + if (qsqr[i] > max) + { + bi = i; + max = qsqr[i]; + } + } - bool too_small = false; - if (qsqr[bi] < evecprec) - { - //if qsqr is still too small, return the identity rotation. - q[bi][0] = 1; - q[bi][1] = 0; - q[bi][2] = 0; - q[bi][3] = 0; - too_small = true; - } - else - { - double normq = sqrt(qsqr[bi]); - q[bi][0] /= normq; - q[bi][1] /= normq; - q[bi][2] /= normq; - q[bi][3] /= normq; - } + bool too_small = false; + if (qsqr[bi] < evecprec) + { + //if qsqr is still too small, return the identity rotation. + q[bi][0] = 1; + q[bi][1] = 0; + q[bi][2] = 0; + q[bi][3] = 0; + too_small = true; + } + else + { + double normq = sqrt(qsqr[bi]); + q[bi][0] /= normq; + q[bi][1] /= normq; + q[bi][2] /= normq; + q[bi][3] /= normq; + } - memcpy(qopt, q[bi], 4 * sizeof(double)); - return !too_small; + memcpy(qopt, q[bi], 4 * sizeof(double)); + return !too_small; } int polar_decomposition_3x3(double* _A, bool right_sided, double* U, double* P) { - double A[9]; - memcpy(A, _A, 9 * sizeof(double)); + double A[9]; + memcpy(A, _A, 9 * sizeof(double)); - double det = matrix_determinant_3x3(A); - if (det < 0) - flip_matrix(A); + double det = matrix_determinant_3x3(A); + if (det < 0) + flip_matrix(A); - double q[4]; - double nrmsdsq = 0; - optimal_quaternion(A, true, -1, &nrmsdsq, q); - q[0] = -q[0]; - quaternion_to_rotation_matrix(q, U); + double q[4]; + double nrmsdsq = 0; + optimal_quaternion(A, true, -1, &nrmsdsq, q); + q[0] = -q[0]; + quaternion_to_rotation_matrix(q, U); - if (det < 0) - flip_matrix(U); + if (det < 0) + flip_matrix(U); - double UT[9] = {U[0], U[3], U[6], U[1], U[4], U[7], U[2], U[5], U[8]}; + double UT[9] = {U[0], U[3], U[6], U[1], U[4], U[7], U[2], U[5], U[8]}; - if (right_sided) - matmul_3x3(UT, _A, P); - else - matmul_3x3(_A, UT, P); + if (right_sided) + matmul_3x3(UT, _A, P); + else + matmul_3x3(_A, UT, P); - return 0; + return 0; } void InnerProduct(double *A, int num, const double (*coords1)[3], double (*coords2)[3], int8_t* permutation) { - A[0] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = 0.0; + A[0] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = 0.0; - for (int i = 0; i < num; ++i) - { - double x1 = coords1[i][0]; - double y1 = coords1[i][1]; - double z1 = coords1[i][2]; + for (int i = 0; i < num; ++i) + { + double x1 = coords1[i][0]; + double y1 = coords1[i][1]; + double z1 = coords1[i][2]; - double x2 = coords2[permutation[i]][0]; - double y2 = coords2[permutation[i]][1]; - double z2 = coords2[permutation[i]][2]; + double x2 = coords2[permutation[i]][0]; + double y2 = coords2[permutation[i]][1]; + double z2 = coords2[permutation[i]][2]; - A[0] += x1 * x2; - A[1] += x1 * y2; - A[2] += x1 * z2; + A[0] += x1 * x2; + A[1] += x1 * y2; + A[2] += x1 * z2; - A[3] += y1 * x2; - A[4] += y1 * y2; - A[5] += y1 * z2; + A[3] += y1 * x2; + A[4] += y1 * y2; + A[5] += y1 * z2; - A[6] += z1 * x2; - A[7] += z1 * y2; - A[8] += z1 * z2; - } + A[6] += z1 * x2; + A[7] += z1 * y2; + A[8] += z1 * z2; + } } int FastCalcRMSDAndRotation(double *A, double E0, double *p_nrmsdsq, double *q, double* U) { - optimal_quaternion(A, false, E0, p_nrmsdsq, q); - quaternion_to_rotation_matrix(q, U); - return 0; + optimal_quaternion(A, false, E0, p_nrmsdsq, q); + quaternion_to_rotation_matrix(q, U); + return 0; } } diff --git a/src/USER-PTM/ptm_quat.cpp b/src/USER-PTM/ptm_quat.cpp index f5764f6bb9..1fcdf7e0a1 100644 --- a/src/USER-PTM/ptm_quat.cpp +++ b/src/USER-PTM/ptm_quat.cpp @@ -19,321 +19,321 @@ namespace ptm { const double generator_cubic[24][4] = { - { 1, 0, 0, 0 }, - { sqrt(2)/2, sqrt(2)/2, 0, 0 }, - { sqrt(2)/2, 0, sqrt(2)/2, 0 }, - { sqrt(2)/2, 0, 0, sqrt(2)/2 }, - { sqrt(2)/2, 0, 0, -sqrt(2)/2 }, - { sqrt(2)/2, 0, -sqrt(2)/2, 0 }, - { sqrt(2)/2, -sqrt(2)/2, -0, -0 }, - { 0.5, 0.5, 0.5, 0.5 }, - { 0.5, 0.5, 0.5, -0.5 }, - { 0.5, 0.5, -0.5, 0.5 }, - { 0.5, 0.5, -0.5, -0.5 }, - { 0.5, -0.5, 0.5, 0.5 }, - { 0.5, -0.5, 0.5, -0.5 }, - { 0.5, -0.5, -0.5, 0.5 }, - { 0.5, -0.5, -0.5, -0.5 }, - { 0, 1, 0, 0 }, - { 0, sqrt(2)/2, sqrt(2)/2, 0 }, - { 0, sqrt(2)/2, 0, sqrt(2)/2 }, - { 0, sqrt(2)/2, 0, -sqrt(2)/2 }, - { 0, sqrt(2)/2, -sqrt(2)/2, 0 }, - { 0, 0, 1, 0 }, - { 0, 0, sqrt(2)/2, sqrt(2)/2 }, - { 0, 0, sqrt(2)/2, -sqrt(2)/2 }, - { 0, 0, 0, 1 }, + { 1, 0, 0, 0 }, + { sqrt(2)/2, sqrt(2)/2, 0, 0 }, + { sqrt(2)/2, 0, sqrt(2)/2, 0 }, + { sqrt(2)/2, 0, 0, sqrt(2)/2 }, + { sqrt(2)/2, 0, 0, -sqrt(2)/2 }, + { sqrt(2)/2, 0, -sqrt(2)/2, 0 }, + { sqrt(2)/2, -sqrt(2)/2, -0, -0 }, + { 0.5, 0.5, 0.5, 0.5 }, + { 0.5, 0.5, 0.5, -0.5 }, + { 0.5, 0.5, -0.5, 0.5 }, + { 0.5, 0.5, -0.5, -0.5 }, + { 0.5, -0.5, 0.5, 0.5 }, + { 0.5, -0.5, 0.5, -0.5 }, + { 0.5, -0.5, -0.5, 0.5 }, + { 0.5, -0.5, -0.5, -0.5 }, + { 0, 1, 0, 0 }, + { 0, sqrt(2)/2, sqrt(2)/2, 0 }, + { 0, sqrt(2)/2, 0, sqrt(2)/2 }, + { 0, sqrt(2)/2, 0, -sqrt(2)/2 }, + { 0, sqrt(2)/2, -sqrt(2)/2, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, sqrt(2)/2, sqrt(2)/2 }, + { 0, 0, sqrt(2)/2, -sqrt(2)/2 }, + { 0, 0, 0, 1 }, }; const double generator_diamond_cubic[12][4] = { - { 1, 0, 0, 0 }, - { 0.5, 0.5, 0.5, 0.5 }, - { 0.5, 0.5, 0.5, -0.5 }, - { 0.5, 0.5, -0.5, 0.5 }, - { 0.5, 0.5, -0.5, -0.5 }, - { 0.5, -0.5, 0.5, 0.5 }, - { 0.5, -0.5, 0.5, -0.5 }, - { 0.5, -0.5, -0.5, 0.5 }, - { 0.5, -0.5, -0.5, -0.5 }, - { 0, 1, 0, 0 }, - { 0, 0, 1, 0 }, - { 0, 0, 0, 1 }, + { 1, 0, 0, 0 }, + { 0.5, 0.5, 0.5, 0.5 }, + { 0.5, 0.5, 0.5, -0.5 }, + { 0.5, 0.5, -0.5, 0.5 }, + { 0.5, 0.5, -0.5, -0.5 }, + { 0.5, -0.5, 0.5, 0.5 }, + { 0.5, -0.5, 0.5, -0.5 }, + { 0.5, -0.5, -0.5, 0.5 }, + { 0.5, -0.5, -0.5, -0.5 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, }; const double generator_hcp[6][4] = { - { 1, 0, 0, 0 }, - { 0.5, 0, 0, sqrt(3)/2 }, - { 0.5, 0, 0, -sqrt(3)/2 }, - { 0, sqrt(3)/2, 0.5, 0 }, - { 0, sqrt(3)/2, -0.5, 0 }, - { 0, 0, 1, 0 }, + { 1, 0, 0, 0 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, + { 0, sqrt(3)/2, 0.5, 0 }, + { 0, sqrt(3)/2, -0.5, 0 }, + { 0, 0, 1, 0 }, }; const double generator_hcp_conventional[12][4] = { - { 1, 0, 0, 0 }, - { sqrt(3)/2, 0, 0, 0.5 }, - { sqrt(3)/2, 0, 0, -0.5 }, - { 0.5, 0, 0, sqrt(3)/2 }, - { 0.5, 0, 0, -sqrt(3)/2 }, - { 0, 1, 0, 0 }, - { 0, sqrt(3)/2, 0.5, 0 }, - { 0, sqrt(3)/2, -0.5, 0 }, - { 0, 0.5, sqrt(3)/2, 0 }, - { 0, 0.5, -sqrt(3)/2, 0 }, - { 0, 0, 1, 0 }, - { 0, 0, 0, 1 }, + { 1, 0, 0, 0 }, + { sqrt(3)/2, 0, 0, 0.5 }, + { sqrt(3)/2, 0, 0, -0.5 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, + { 0, 1, 0, 0 }, + { 0, sqrt(3)/2, 0.5, 0 }, + { 0, sqrt(3)/2, -0.5, 0 }, + { 0, 0.5, sqrt(3)/2, 0 }, + { 0, 0.5, -sqrt(3)/2, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, }; const double generator_diamond_hexagonal[3][4] = { - { 1, 0, 0, 0 }, - { 0.5, 0, 0, sqrt(3)/2 }, - { 0.5, 0, 0, -sqrt(3)/2 }, + { 1, 0, 0, 0 }, + { 0.5, 0, 0, sqrt(3)/2 }, + { 0.5, 0, 0, -sqrt(3)/2 }, }; const double generator_icosahedral[60][4] = { - { 1, 0, 0, 0 }, - { (1+sqrt(5))/4, 0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, 0, sqrt(50-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, 0, 0, sqrt(5./8-sqrt(5)/8) }, - { (1+sqrt(5))/4, 0, 0, -sqrt(5./8-sqrt(5)/8) }, - { (1+sqrt(5))/4, 0, -sqrt(50-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, -0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, - { (1+sqrt(5))/4, -0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, - { 0.5, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, - { 0.5, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, - { 0.5, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, - { 0.5, 0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, - { 0.5, 0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, - { 0.5, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, - { 0.5, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, - { 0.5, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, - { 0.5, 0, sqrt((5+sqrt(5))/10), -sqrt(25-10*sqrt(5))/10 }, - { 0.5, 0, sqrt(50-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, - { 0.5, 0, -sqrt(50-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, - { 0.5, 0, -sqrt((5+sqrt(5))/10), sqrt(25-10*sqrt(5))/10 }, - { 0.5, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, - { 0.5, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, - { 0.5, -0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, - { 0.5, -0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, - { 0.5, -0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, - { 0.5, -0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, - { 0.5, -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, - { 0.5, -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, - { 1/(1+sqrt(5)), (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), 0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), 0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), 0, sqrt((5+sqrt(5))/10), sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), 0, 0, sqrt(1-1/(2*sqrt(5)+6)) }, - { 1/(1+sqrt(5)), 0, 0, -sqrt(1-1/(2*sqrt(5)+6)) }, - { 1/(1+sqrt(5)), 0, -sqrt((5+sqrt(5))/10), -sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), -0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), -0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, - { 1/(1+sqrt(5)), -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, - { 0, 1, 0, 0 }, - { 0, (1+sqrt(5))/4, sqrt(5./8-sqrt(5)/8), 0 }, - { 0, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(50-10*sqrt(5))/10 }, - { 0, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(50-10*sqrt(5))/10 }, - { 0, (1+sqrt(5))/4, -sqrt(5./8-sqrt(5)/8), 0 }, - { 0, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(50-10*sqrt(5))/10 }, - { 0, 0.5, sqrt(25-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, - { 0, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt((5+sqrt(5))/10) }, - { 0, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(50-10*sqrt(5))/10 }, - { 0, 1/(1+sqrt(5)), sqrt(1-1/(2*sqrt(5)+6)), 0 }, - { 0, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt((5+sqrt(5))/10) }, - { 0, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt((5+sqrt(5))/10) }, - { 0, 1/(1+sqrt(5)), -sqrt(1-1/(2*sqrt(5)+6)), 0 }, - { 0, 0, sqrt((5+sqrt(5))/10), -sqrt(50-10*sqrt(5))/10 }, - { 0, 0, sqrt(50-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, + { 1, 0, 0, 0 }, + { (1+sqrt(5))/4, 0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0, sqrt(50-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, 0, 0, sqrt(5./8-sqrt(5)/8) }, + { (1+sqrt(5))/4, 0, 0, -sqrt(5./8-sqrt(5)/8) }, + { (1+sqrt(5))/4, 0, -sqrt(50-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -0.5, sqrt(25-10*sqrt(5))/10, sqrt(50-10*sqrt(5))/20 }, + { (1+sqrt(5))/4, -0.5, -sqrt(25-10*sqrt(5))/10, -sqrt(50-10*sqrt(5))/20 }, + { 0.5, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, + { 0.5, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, sqrt((5+sqrt(5))/10), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, 0, sqrt(50-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, -sqrt(50-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, 0, -sqrt((5+sqrt(5))/10), sqrt(25-10*sqrt(5))/10 }, + { 0.5, -1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, sqrt((5+2*sqrt(5))/20) }, + { 0.5, -1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, sqrt((5+2*sqrt(5))/20), sqrt(25-10*sqrt(5))/10 }, + { 0.5, -0.5, sqrt(25-10*sqrt(5))/10, -sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, -sqrt(25-10*sqrt(5))/10, sqrt((5+2*sqrt(5))/20) }, + { 0.5, -0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(25-10*sqrt(5))/10 }, + { 0.5, -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(25-10*sqrt(5))/10 }, + { 0.5, -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(25-10*sqrt(5))/10 }, + { 1/(1+sqrt(5)), (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0, sqrt((5+sqrt(5))/10), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), 0, 0, sqrt(1-1/(2*sqrt(5)+6)) }, + { 1/(1+sqrt(5)), 0, 0, -sqrt(1-1/(2*sqrt(5)+6)) }, + { 1/(1+sqrt(5)), 0, -sqrt((5+sqrt(5))/10), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -0.5, sqrt((5+2*sqrt(5))/20), -sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -0.5, -sqrt((5+2*sqrt(5))/20), sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -(1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, sqrt(10*sqrt(5)+50)/20 }, + { 1/(1+sqrt(5)), -(1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, -sqrt(10*sqrt(5)+50)/20 }, + { 0, 1, 0, 0 }, + { 0, (1+sqrt(5))/4, sqrt(5./8-sqrt(5)/8), 0 }, + { 0, (1+sqrt(5))/4, sqrt(50-10*sqrt(5))/20, -sqrt(50-10*sqrt(5))/10 }, + { 0, (1+sqrt(5))/4, -sqrt(50-10*sqrt(5))/20, sqrt(50-10*sqrt(5))/10 }, + { 0, (1+sqrt(5))/4, -sqrt(5./8-sqrt(5)/8), 0 }, + { 0, 0.5, sqrt((5+2*sqrt(5))/20), sqrt(50-10*sqrt(5))/10 }, + { 0, 0.5, sqrt(25-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, + { 0, 0.5, -sqrt(25-10*sqrt(5))/10, -sqrt((5+sqrt(5))/10) }, + { 0, 0.5, -sqrt((5+2*sqrt(5))/20), -sqrt(50-10*sqrt(5))/10 }, + { 0, 1/(1+sqrt(5)), sqrt(1-1/(2*sqrt(5)+6)), 0 }, + { 0, 1/(1+sqrt(5)), sqrt(10*sqrt(5)+50)/20, -sqrt((5+sqrt(5))/10) }, + { 0, 1/(1+sqrt(5)), -sqrt(10*sqrt(5)+50)/20, sqrt((5+sqrt(5))/10) }, + { 0, 1/(1+sqrt(5)), -sqrt(1-1/(2*sqrt(5)+6)), 0 }, + { 0, 0, sqrt((5+sqrt(5))/10), -sqrt(50-10*sqrt(5))/10 }, + { 0, 0, sqrt(50-10*sqrt(5))/10, sqrt((5+sqrt(5))/10) }, }; static void quat_rot(double* r, double* a, double* b) { - b[0] = (r[0] * a[0] - r[1] * a[1] - r[2] * a[2] - r[3] * a[3]); - b[1] = (r[0] * a[1] + r[1] * a[0] + r[2] * a[3] - r[3] * a[2]); - b[2] = (r[0] * a[2] - r[1] * a[3] + r[2] * a[0] + r[3] * a[1]); - b[3] = (r[0] * a[3] + r[1] * a[2] - r[2] * a[1] + r[3] * a[0]); + b[0] = (r[0] * a[0] - r[1] * a[1] - r[2] * a[2] - r[3] * a[3]); + b[1] = (r[0] * a[1] + r[1] * a[0] + r[2] * a[3] - r[3] * a[2]); + b[2] = (r[0] * a[2] - r[1] * a[3] + r[2] * a[0] + r[3] * a[1]); + b[3] = (r[0] * a[3] + r[1] * a[2] - r[2] * a[1] + r[3] * a[0]); } static int rotate_quaternion_into_fundamental_zone(int num_generators, const double (*generator)[4], double* q) { - double max = 0.0; - int i = 0, bi = -1; - for (i=0;i max) - { - max = t; - bi = i; - } - } + double max = 0.0; + int i = 0, bi = -1; + for (i=0;i max) + { + max = t; + bi = i; + } + } - double f[4]; - quat_rot(q, (double*)generator[bi], f); - memcpy(q, &f, 4 * sizeof(double)); - if (q[0] < 0) - { - q[0] = -q[0]; - q[1] = -q[1]; - q[2] = -q[2]; - q[3] = -q[3]; - } + double f[4]; + quat_rot(q, (double*)generator[bi], f); + memcpy(q, &f, 4 * sizeof(double)); + if (q[0] < 0) + { + q[0] = -q[0]; + q[1] = -q[1]; + q[2] = -q[2]; + q[3] = -q[3]; + } - return bi; + return bi; } int rotate_quaternion_into_cubic_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(24, generator_cubic, q); + return rotate_quaternion_into_fundamental_zone(24, generator_cubic, q); } int rotate_quaternion_into_diamond_cubic_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(12, generator_diamond_cubic, q); + return rotate_quaternion_into_fundamental_zone(12, generator_diamond_cubic, q); } int rotate_quaternion_into_icosahedral_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(60, generator_icosahedral, q); + return rotate_quaternion_into_fundamental_zone(60, generator_icosahedral, q); } int rotate_quaternion_into_hcp_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(6, generator_hcp, q); + return rotate_quaternion_into_fundamental_zone(6, generator_hcp, q); } int rotate_quaternion_into_hcp_conventional_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(12, generator_hcp_conventional, q); + return rotate_quaternion_into_fundamental_zone(12, generator_hcp_conventional, q); } int rotate_quaternion_into_diamond_hexagonal_fundamental_zone(double* q) { - return rotate_quaternion_into_fundamental_zone(3, generator_diamond_hexagonal, q); + return rotate_quaternion_into_fundamental_zone(3, generator_diamond_hexagonal, q); } double quat_dot(double* a, double* b) { - return a[0] * b[0] - + a[1] * b[1] - + a[2] * b[2] - + a[3] * b[3]; + return a[0] * b[0] + + a[1] * b[1] + + a[2] * b[2] + + a[3] * b[3]; } double quat_size(double* q) { - return sqrt(quat_dot(q, q)); + return sqrt(quat_dot(q, q)); } void normalize_quaternion(double* q) { - double size = quat_size(q); + double size = quat_size(q); - q[0] /= size; - q[1] /= size; - q[2] /= size; - q[3] /= size; + q[0] /= size; + q[1] /= size; + q[2] /= size; + q[3] /= size; } void quaternion_to_rotation_matrix(double* q, double* u) { - double a = q[0]; - double b = q[1]; - double c = q[2]; - double d = q[3]; + double a = q[0]; + double b = q[1]; + double c = q[2]; + double d = q[3]; - u[0] = a*a + b*b - c*c - d*d; - u[1] = 2*b*c - 2*a*d; - u[2] = 2*b*d + 2*a*c; + u[0] = a*a + b*b - c*c - d*d; + u[1] = 2*b*c - 2*a*d; + u[2] = 2*b*d + 2*a*c; - u[3] = 2*b*c + 2*a*d; - u[4] = a*a - b*b + c*c - d*d; - u[5] = 2*c*d - 2*a*b; + u[3] = 2*b*c + 2*a*d; + u[4] = a*a - b*b + c*c - d*d; + u[5] = 2*c*d - 2*a*b; - u[6] = 2*b*d - 2*a*c; - u[7] = 2*c*d + 2*a*b; - u[8] = a*a - b*b - c*c + d*d; + u[6] = 2*b*d - 2*a*c; + u[7] = 2*c*d + 2*a*b; + u[8] = a*a - b*b - c*c + d*d; } void rotation_matrix_to_quaternion(double* u, double* q) { - double r11 = u[0]; - double r12 = u[1]; - double r13 = u[2]; - double r21 = u[3]; - double r22 = u[4]; - double r23 = u[5]; - double r31 = u[6]; - double r32 = u[7]; - double r33 = u[8]; + double r11 = u[0]; + double r12 = u[1]; + double r13 = u[2]; + double r21 = u[3]; + double r22 = u[4]; + double r23 = u[5]; + double r31 = u[6]; + double r32 = u[7]; + double r33 = u[8]; - q[0] = (1.0 + r11 + r22 + r33) / 4.0; - q[1] = (1.0 + r11 - r22 - r33) / 4.0; - q[2] = (1.0 - r11 + r22 - r33) / 4.0; - q[3] = (1.0 - r11 - r22 + r33) / 4.0; + q[0] = (1.0 + r11 + r22 + r33) / 4.0; + q[1] = (1.0 + r11 - r22 - r33) / 4.0; + q[2] = (1.0 - r11 + r22 - r33) / 4.0; + q[3] = (1.0 - r11 - r22 + r33) / 4.0; - q[0] = sqrt(std::max(0., q[0])); - q[1] = sqrt(std::max(0., q[1])); - q[2] = sqrt(std::max(0., q[2])); - q[3] = sqrt(std::max(0., q[3])); + q[0] = sqrt(std::max(0., q[0])); + q[1] = sqrt(std::max(0., q[1])); + q[2] = sqrt(std::max(0., q[2])); + q[3] = sqrt(std::max(0., q[3])); - double m0 = std::max(q[0], q[1]); - double m1 = std::max(q[2], q[3]); - double max = std::max(m0, m1); + double m0 = std::max(q[0], q[1]); + double m1 = std::max(q[2], q[3]); + double max = std::max(m0, m1); - int i = 0; - for (i=0;i<4;i++) - if (q[i] == max) - break; + int i = 0; + for (i=0;i<4;i++) + if (q[i] == max) + break; - if (i == 0) - { - q[1] *= SIGN(r32 - r23); - q[2] *= SIGN(r13 - r31); - q[3] *= SIGN(r21 - r12); - } - else if (i == 1) - { - q[0] *= SIGN(r32 - r23); - q[2] *= SIGN(r21 + r12); - q[3] *= SIGN(r13 + r31); - } - else if (i == 2) - { - q[0] *= SIGN(r13 - r31); - q[1] *= SIGN(r21 + r12); - q[3] *= SIGN(r32 + r23); - } - else if (i == 3) - { - q[0] *= SIGN(r21 - r12); - q[1] *= SIGN(r31 + r13); - q[2] *= SIGN(r32 + r23); - } + if (i == 0) + { + q[1] *= SIGN(r32 - r23); + q[2] *= SIGN(r13 - r31); + q[3] *= SIGN(r21 - r12); + } + else if (i == 1) + { + q[0] *= SIGN(r32 - r23); + q[2] *= SIGN(r21 + r12); + q[3] *= SIGN(r13 + r31); + } + else if (i == 2) + { + q[0] *= SIGN(r13 - r31); + q[1] *= SIGN(r21 + r12); + q[3] *= SIGN(r32 + r23); + } + else if (i == 3) + { + q[0] *= SIGN(r21 - r12); + q[1] *= SIGN(r31 + r13); + q[2] *= SIGN(r32 + r23); + } - normalize_quaternion(q); + normalize_quaternion(q); } double quat_quick_misorientation(double* q1, double* q2) { - double t = quat_dot(q1, q2); - t = std::min(1., std::max(-1., t)); - return 2 * t * t - 1; + double t = quat_dot(q1, q2); + t = std::min(1., std::max(-1., t)); + return 2 * t * t - 1; } double quat_misorientation(double* q1, double* q2) { - return acos(quat_quick_misorientation(q1, q2)); + return acos(quat_quick_misorientation(q1, q2)); } } diff --git a/src/USER-PTM/ptm_structure_matcher.cpp b/src/USER-PTM/ptm_structure_matcher.cpp index 055a2bf3b0..63bcfade67 100644 --- a/src/USER-PTM/ptm_structure_matcher.cpp +++ b/src/USER-PTM/ptm_structure_matcher.cpp @@ -27,349 +27,349 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace ptm { static double calc_rmsd(int num_points, const double (*ideal_points)[3], double (*normalized)[3], int8_t* mapping, - double G1, double G2, double E0, double* q, double* p_scale) + double G1, double G2, double E0, double* q, double* p_scale) { - double A0[9]; - InnerProduct(A0, num_points, ideal_points, normalized, mapping); + double A0[9]; + InnerProduct(A0, num_points, ideal_points, normalized, mapping); - double nrmsdsq, rot[9]; - FastCalcRMSDAndRotation(A0, E0, &nrmsdsq, q, rot); + double nrmsdsq, rot[9]; + FastCalcRMSDAndRotation(A0, E0, &nrmsdsq, q, rot); - double k0 = 0; - for (int i=0;inum_nbrs + 1; - const double (*ideal_points)[3] = s->points; - int8_t inverse_labelling[PTM_MAX_POINTS]; - int8_t mapping[PTM_MAX_POINTS]; + int num_points = s->num_nbrs + 1; + const double (*ideal_points)[3] = s->points; + int8_t inverse_labelling[PTM_MAX_POINTS]; + int8_t mapping[PTM_MAX_POINTS]; - for (int i=0; inum_graphs;i++) - { - if (hash != s->graphs[i].hash) - continue; + for (int i = 0;inum_graphs;i++) + { + if (hash != s->graphs[i].hash) + continue; - graph_t* gref = &s->graphs[i]; - for (int j = 0;jnum_automorphisms;j++) - { - for (int k=0;kautomorphism_index + j][k]] = inverse_labelling[ gref->canonical_labelling[k] ]; + graph_t* gref = &s->graphs[i]; + for (int j = 0;jnum_automorphisms;j++) + { + for (int k=0;kautomorphism_index + j][k]] = inverse_labelling[ gref->canonical_labelling[k] ]; - double q[4], scale = 0; - double rmsd = calc_rmsd(num_points, ideal_points, normalized, mapping, G1, G2, E0, q, &scale); - if (rmsd < res->rmsd) - { - res->rmsd = rmsd; - res->scale = scale; - res->ref_struct = s; - memcpy(res->q, q, 4 * sizeof(double)); - memcpy(res->mapping, mapping, sizeof(int8_t) * num_points); - } - } - } + double q[4], scale = 0; + double rmsd = calc_rmsd(num_points, ideal_points, normalized, mapping, G1, G2, E0, q, &scale); + if (rmsd < res->rmsd) + { + res->rmsd = rmsd; + res->scale = scale; + res->ref_struct = s; + memcpy(res->q, q, 4 * sizeof(double)); + memcpy(res->mapping, mapping, sizeof(int8_t) * num_points); + } + } + } } int match_general(const refdata_t* s, double (*ch_points)[3], double (*points)[3], convexhull_t* ch, result_t* res) { - int8_t degree[PTM_MAX_NBRS]; - int8_t facets[PTM_MAX_FACETS][3]; + int8_t degree[PTM_MAX_NBRS]; + int8_t facets[PTM_MAX_FACETS][3]; - int ret = get_convex_hull(s->num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); - ch->ok = ret >= 0; - if (ret != 0) - return PTM_NO_ERROR; + int ret = get_convex_hull(s->num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); + ch->ok = ret >= 0; + if (ret != 0) + return PTM_NO_ERROR; - if (ch->num_facets != s->num_facets) - return PTM_NO_ERROR; //incorrect number of facets in convex hull + if (ch->num_facets != s->num_facets) + return PTM_NO_ERROR; //incorrect number of facets in convex hull - int max_degree = graph_degree(s->num_facets, facets, s->num_nbrs, degree); - if (max_degree > s->max_degree) - return PTM_NO_ERROR; + int max_degree = graph_degree(s->num_facets, facets, s->num_nbrs, degree); + if (max_degree > s->max_degree) + return PTM_NO_ERROR; - if (s->type == PTM_MATCH_SC) - for (int i = 0;inum_nbrs;i++) - if (degree[i] != 4) - return PTM_NO_ERROR; + if (s->type == PTM_MATCH_SC) + for (int i = 0;inum_nbrs;i++) + if (degree[i] != 4) + return PTM_NO_ERROR; - double normalized[PTM_MAX_POINTS][3]; - subtract_barycentre(s->num_nbrs + 1, points, normalized); + double normalized[PTM_MAX_POINTS][3]; + subtract_barycentre(s->num_nbrs + 1, points, normalized); - int8_t code[2 * PTM_MAX_EDGES]; - int8_t colours[PTM_MAX_POINTS] = {0}; - int8_t canonical_labelling[PTM_MAX_POINTS]; - uint64_t hash = 0; - ret = canonical_form_coloured(s->num_facets, facets, s->num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); - if (ret != PTM_NO_ERROR) - return ret; + int8_t code[2 * PTM_MAX_EDGES]; + int8_t colours[PTM_MAX_POINTS] = {0}; + int8_t canonical_labelling[PTM_MAX_POINTS]; + uint64_t hash = 0; + ret = canonical_form_coloured(s->num_facets, facets, s->num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); + if (ret != PTM_NO_ERROR) + return ret; - check_graphs(s, hash, canonical_labelling, normalized, res); - return PTM_NO_ERROR; + check_graphs(s, hash, canonical_labelling, normalized, res); + return PTM_NO_ERROR; } int match_fcc_hcp_ico(double (*ch_points)[3], double (*points)[3], int32_t flags, convexhull_t* ch, result_t* res) { - int num_nbrs = structure_fcc.num_nbrs; - int num_facets = structure_fcc.num_facets; - int max_degree = structure_fcc.max_degree; + int num_nbrs = structure_fcc.num_nbrs; + int num_facets = structure_fcc.num_facets; + int max_degree = structure_fcc.max_degree; - int8_t degree[PTM_MAX_NBRS]; - int8_t facets[PTM_MAX_FACETS][3]; + int8_t degree[PTM_MAX_NBRS]; + int8_t facets[PTM_MAX_FACETS][3]; - int ret = get_convex_hull(num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); - ch->ok = ret >= 0; - if (ret != 0) - return PTM_NO_ERROR; + int ret = get_convex_hull(num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); + ch->ok = ret >= 0; + if (ret != 0) + return PTM_NO_ERROR; - if (ch->num_facets != num_facets) - return PTM_NO_ERROR; //incorrect number of facets in convex hull + if (ch->num_facets != num_facets) + return PTM_NO_ERROR; //incorrect number of facets in convex hull - int _max_degree = graph_degree(num_facets, facets, num_nbrs, degree); - if (_max_degree > max_degree) - return PTM_NO_ERROR; + int _max_degree = graph_degree(num_facets, facets, num_nbrs, degree); + if (_max_degree > max_degree) + return PTM_NO_ERROR; - double normalized[PTM_MAX_POINTS][3]; - subtract_barycentre(num_nbrs + 1, points, normalized); + double normalized[PTM_MAX_POINTS][3]; + subtract_barycentre(num_nbrs + 1, points, normalized); - int8_t code[2 * PTM_MAX_EDGES]; - int8_t colours[PTM_MAX_POINTS] = {0}; - int8_t canonical_labelling[PTM_MAX_POINTS]; - uint64_t hash = 0; - ret = canonical_form_coloured(num_facets, facets, num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); - if (ret != PTM_NO_ERROR) - return ret; + int8_t code[2 * PTM_MAX_EDGES]; + int8_t colours[PTM_MAX_POINTS] = {0}; + int8_t canonical_labelling[PTM_MAX_POINTS]; + uint64_t hash = 0; + ret = canonical_form_coloured(num_facets, facets, num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); + if (ret != PTM_NO_ERROR) + return ret; - if (flags & PTM_CHECK_FCC) check_graphs(&structure_fcc, hash, canonical_labelling, normalized, res); - if (flags & PTM_CHECK_HCP) check_graphs(&structure_hcp, hash, canonical_labelling, normalized, res); - if (flags & PTM_CHECK_ICO) check_graphs(&structure_ico, hash, canonical_labelling, normalized, res); - return PTM_NO_ERROR; + if (flags & PTM_CHECK_FCC) check_graphs(&structure_fcc, hash, canonical_labelling, normalized, res); + if (flags & PTM_CHECK_HCP) check_graphs(&structure_hcp, hash, canonical_labelling, normalized, res); + if (flags & PTM_CHECK_ICO) check_graphs(&structure_ico, hash, canonical_labelling, normalized, res); + return PTM_NO_ERROR; } int match_dcub_dhex(double (*ch_points)[3], double (*points)[3], int32_t flags, convexhull_t* ch, result_t* res) { - int num_nbrs = structure_dcub.num_nbrs; - int num_facets = structure_fcc.num_facets; - int max_degree = structure_dcub.max_degree; + int num_nbrs = structure_dcub.num_nbrs; + int num_facets = structure_fcc.num_facets; + int max_degree = structure_dcub.max_degree; - int8_t facets[PTM_MAX_FACETS][3]; - int ret = get_convex_hull(num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); - ch->ok = ret >= 0; - if (ret != 0) - return PTM_NO_ERROR; + int8_t facets[PTM_MAX_FACETS][3]; + int ret = get_convex_hull(num_nbrs + 1, (const double (*)[3])ch_points, ch, facets); + ch->ok = ret >= 0; + if (ret != 0) + return PTM_NO_ERROR; - //check for facets with multiple inner atoms - bool inverted[4] = {false, false, false, false}; - for (int i=0;inum_facets;i++) - { - int n = 0; - for (int j=0;j<3;j++) - { - if (facets[i][j] <= 3) - { - inverted[facets[i][j]] = true; - n++; - } - } - if (n > 1) - return PTM_NO_ERROR; - } + //check for facets with multiple inner atoms + bool inverted[4] = {false, false, false, false}; + for (int i=0;inum_facets;i++) + { + int n = 0; + for (int j=0;j<3;j++) + { + if (facets[i][j] <= 3) + { + inverted[facets[i][j]] = true; + n++; + } + } + if (n > 1) + return PTM_NO_ERROR; + } - int num_inverted = 0; - for (int i=0;i<4;i++) - num_inverted += inverted[i] ? 1 : 0; + int num_inverted = 0; + for (int i=0;i<4;i++) + num_inverted += inverted[i] ? 1 : 0; - if (ch->num_facets != num_facets + 2 * num_inverted) - return PTM_NO_ERROR; //incorrect number of facets in convex hull + if (ch->num_facets != num_facets + 2 * num_inverted) + return PTM_NO_ERROR; //incorrect number of facets in convex hull - int8_t degree[PTM_MAX_NBRS]; - int _max_degree = graph_degree(num_facets, facets, num_nbrs, degree); - if (_max_degree > max_degree) - return PTM_NO_ERROR; + int8_t degree[PTM_MAX_NBRS]; + int _max_degree = graph_degree(num_facets, facets, num_nbrs, degree); + if (_max_degree > max_degree) + return PTM_NO_ERROR; - int num_found = 0; - int8_t toadd[4][3]; - for (int i=0;inum_facets;i++) - { - int a = facets[i][0]; - int b = facets[i][1]; - int c = facets[i][2]; - if (a <= 3 || b <= 3 || c <= 3) - continue; + int num_found = 0; + int8_t toadd[4][3]; + for (int i=0;inum_facets;i++) + { + int a = facets[i][0]; + int b = facets[i][1]; + int c = facets[i][2]; + if (a <= 3 || b <= 3 || c <= 3) + continue; - int i0 = (a - 4) / 3; - int i1 = (b - 4) / 3; - int i2 = (c - 4) / 3; + int i0 = (a - 4) / 3; + int i1 = (b - 4) / 3; + int i2 = (c - 4) / 3; - if (i0 == i1 && i0 == i2) - { - if (num_found + num_inverted >= 4) - return PTM_NO_ERROR; + if (i0 == i1 && i0 == i2) + { + if (num_found + num_inverted >= 4) + return PTM_NO_ERROR; - toadd[num_found][0] = a; - toadd[num_found][1] = b; - toadd[num_found][2] = c; - num_found++; + toadd[num_found][0] = a; + toadd[num_found][1] = b; + toadd[num_found][2] = c; + num_found++; - memcpy(&facets[i], &facets[ch->num_facets - 1], 3 * sizeof(int8_t)); - ch->num_facets--; - i--; - } - } + memcpy(&facets[i], &facets[ch->num_facets - 1], 3 * sizeof(int8_t)); + ch->num_facets--; + i--; + } + } - if (num_found + num_inverted != 4) - return PTM_NO_ERROR; + if (num_found + num_inverted != 4) + return PTM_NO_ERROR; - for (int i=0;inum_facets][0] = i0; - facets[ch->num_facets][1] = b; - facets[ch->num_facets][2] = c; - ch->num_facets++; + facets[ch->num_facets][0] = i0; + facets[ch->num_facets][1] = b; + facets[ch->num_facets][2] = c; + ch->num_facets++; - facets[ch->num_facets][0] = a; - facets[ch->num_facets][1] = i0; - facets[ch->num_facets][2] = c; - ch->num_facets++; + facets[ch->num_facets][0] = a; + facets[ch->num_facets][1] = i0; + facets[ch->num_facets][2] = c; + ch->num_facets++; - facets[ch->num_facets][0] = a; - facets[ch->num_facets][1] = b; - facets[ch->num_facets][2] = i0; - ch->num_facets++; - } + facets[ch->num_facets][0] = a; + facets[ch->num_facets][1] = b; + facets[ch->num_facets][2] = i0; + ch->num_facets++; + } - _max_degree = graph_degree(ch->num_facets, facets, num_nbrs, degree); - if (_max_degree > max_degree) - return PTM_NO_ERROR; + _max_degree = graph_degree(ch->num_facets, facets, num_nbrs, degree); + if (_max_degree > max_degree) + return PTM_NO_ERROR; - double normalized[PTM_MAX_POINTS][3]; - subtract_barycentre(num_nbrs + 1, points, normalized); + double normalized[PTM_MAX_POINTS][3]; + subtract_barycentre(num_nbrs + 1, points, normalized); - int8_t code[2 * PTM_MAX_EDGES]; - int8_t colours[PTM_MAX_POINTS] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int8_t canonical_labelling[PTM_MAX_POINTS]; - uint64_t hash = 0; - ret = canonical_form_coloured(ch->num_facets, facets, num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); - if (ret != PTM_NO_ERROR) - return ret; + int8_t code[2 * PTM_MAX_EDGES]; + int8_t colours[PTM_MAX_POINTS] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int8_t canonical_labelling[PTM_MAX_POINTS]; + uint64_t hash = 0; + ret = canonical_form_coloured(ch->num_facets, facets, num_nbrs, degree, colours, canonical_labelling, &code[0], &hash); + if (ret != PTM_NO_ERROR) + return ret; - if (flags & PTM_CHECK_DCUB) check_graphs(&structure_dcub, hash, canonical_labelling, normalized, res); - if (flags & PTM_CHECK_DHEX) check_graphs(&structure_dhex, hash, canonical_labelling, normalized, res); + if (flags & PTM_CHECK_DCUB) check_graphs(&structure_dcub, hash, canonical_labelling, normalized, res); + if (flags & PTM_CHECK_DHEX) check_graphs(&structure_dhex, hash, canonical_labelling, normalized, res); - return PTM_NO_ERROR; + return PTM_NO_ERROR; } -static void check_graphs_graphene( const refdata_t* s, - int num_points, - const double (*ideal_points)[3], - double (*normalized)[3], - int8_t* mapping, - result_t* res) +static void check_graphs_graphene( const refdata_t* s, + int num_points, + const double (*ideal_points)[3], + double (*normalized)[3], + int8_t* mapping, + result_t* res) { - double G1 = 0, G2 = 0; - for (int i=0;irmsd) - { - res->rmsd = rmsd; - res->scale = scale; - res->ref_struct = s; - memcpy(res->q, q, 4 * sizeof(double)); - memcpy(res->mapping, mapping, sizeof(int8_t) * num_points); - } + double q[4], scale = 0; + double rmsd = calc_rmsd(num_points, ideal_points, normalized, mapping, G1, G2, E0, q, &scale); + if (rmsd < res->rmsd) + { + res->rmsd = rmsd; + res->scale = scale; + res->ref_struct = s; + memcpy(res->q, q, 4 * sizeof(double)); + memcpy(res->mapping, mapping, sizeof(int8_t) * num_points); + } } int match_graphene(double (*points)[3], result_t* res) { - int num_nbrs = structure_graphene.num_nbrs; - int num_points = num_nbrs + 1; - const double (*ideal_points)[3] = structure_graphene.points; + int num_nbrs = structure_graphene.num_nbrs; + int num_points = num_nbrs + 1; + const double (*ideal_points)[3] = structure_graphene.points; - double normalized[PTM_MAX_POINTS][3]; - subtract_barycentre(num_points, points, normalized); + double normalized[PTM_MAX_POINTS][3]; + subtract_barycentre(num_points, points, normalized); - int8_t mapping[PTM_MAX_POINTS]; - for (int i=0;i=0;i--) if(mem[i]>0) delete [] mep[i]; - delete [] marg; - delete [] ds2;delete [] ds; - delete [] mep;delete [] mec; - delete [] mem;delete [] pts; - delete [] nu;delete [] ed; + for(int i=current_vertex_order-1;i>=0;i--) if(mem[i]>0) delete [] mep[i]; + delete [] marg; + delete [] ds2;delete [] ds; + delete [] mep;delete [] mec; + delete [] mem;delete [] pts; + delete [] nu;delete [] ed; } /** Ensures that enough memory is allocated prior to carrying out a copy. @@ -103,9 +103,9 @@ voronoicell_base::~voronoicell_base() { * \param[in] vb a pointered to the class to be copied. */ template void voronoicell_base::check_memory_for_copy(vc_class &vc,voronoicell_base* vb) { - while(current_vertex_ordercurrent_vertex_order) add_memory_vorder(vc); - for(int i=0;imec[i]) add_memory(vc,i,ds2); - while(current_verticesp) add_memory_vertices(vc); + while(current_vertex_ordercurrent_vertex_order) add_memory_vorder(vc); + for(int i=0;imec[i]) add_memory(vc,i,ds2); + while(current_verticesp) add_memory_vertices(vc); } /** Increases the memory storage for a particular vertex order, by increasing @@ -121,50 +121,50 @@ void voronoicell_base::check_memory_for_copy(vc_class &vc,voronoicell_base* vb) * \param[in] i the order of the vertex memory to be increased. */ template void voronoicell_base::add_memory(vc_class &vc,int i,int *stackp2) { - int s=(i<<1)+1; - if(mem[i]==0) { - vc.n_allocate(i,init_n_vertices); - mep[i]=new int[init_n_vertices*s]; - mem[i]=init_n_vertices; + int s=(i<<1)+1; + if(mem[i]==0) { + vc.n_allocate(i,init_n_vertices); + mep[i]=new int[init_n_vertices*s]; + mem[i]=init_n_vertices; #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Order %d vertex memory created\n",i); + fprintf(stderr,"Order %d vertex memory created\n",i); #endif - } else { - int j=0,k,*l; - mem[i]<<=1; - if(mem[i]>max_n_vertices) voro_fatal_error("Point memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + } else { + int j=0,k,*l; + mem[i]<<=1; + if(mem[i]>max_n_vertices) voro_fatal_error("Point memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Order %d vertex memory scaled up to %d\n",i,mem[i]); + fprintf(stderr,"Order %d vertex memory scaled up to %d\n",i,mem[i]); #endif - l=new int[s*mem[i]]; - int m=0; - vc.n_allocate_aux1(i); - while(j=0) { - ed[k]=l+j; - vc.n_set_to_aux1_offset(k,m); - } else { - int *dsp; - for(dsp=ds2;dsp=0) { + ed[k]=l+j; + vc.n_set_to_aux1_offset(k,m); + } else { + int *dsp; + for(dsp=ds2;dsp=3 - fputs("Relocated dangling pointer",stderr); + fputs("Relocated dangling pointer",stderr); #endif - } - for(k=0;kmax_vertices) voro_fatal_error("Vertex memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + int i=(current_vertices<<1),j,**pp,*pnu; + if(i>max_vertices) voro_fatal_error("Vertex memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Vertex memory scaled up to %d\n",i); + fprintf(stderr,"Vertex memory scaled up to %d\n",i); #endif - double *ppts; - pp=new int*[i]; - for(j=0;j void voronoicell_base::add_memory_vorder(vc_class &vc) { - int i=(current_vertex_order<<1),j,*p1,**p2; - if(i>max_vertex_order) voro_fatal_error("Vertex order memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + int i=(current_vertex_order<<1),j,*p1,**p2; + if(i>max_vertex_order) voro_fatal_error("Vertex order memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Vertex order memory scaled up to %d\n",i); + fprintf(stderr,"Vertex order memory scaled up to %d\n",i); #endif - p1=new int[i]; - for(j=0;jmax_delete_size) voro_fatal_error("Delete stack 1 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + current_delete_size<<=1; + if(current_delete_size>max_delete_size) voro_fatal_error("Delete stack 1 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Delete stack 1 memory scaled up to %d\n",current_delete_size); + fprintf(stderr,"Delete stack 1 memory scaled up to %d\n",current_delete_size); #endif - int *dsn=new int[current_delete_size],*dsnp=dsn,*dsp=ds; - while(dspmax_delete2_size) voro_fatal_error("Delete stack 2 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + current_delete2_size<<=1; + if(current_delete2_size>max_delete2_size) voro_fatal_error("Delete stack 2 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Delete stack 2 memory scaled up to %d\n",current_delete2_size); + fprintf(stderr,"Delete stack 2 memory scaled up to %d\n",current_delete2_size); #endif - int *dsn=new int[current_delete2_size],*dsnp=dsn,*dsp=ds2; - while(dsp inline bool voronoicell_base::search_for_outside_edge(vc_class &vc,int &up) { - int i,lp,lw,*j(ds2),*stackp2(ds2); - double l; - *(stackp2++)=up; - while(j inline void voronoicell_base::add_to_stack(vc_class &vc,int lp,int *&stackp2) { (void)vc; - for(int *k(ds2);k bool voronoicell_base::nplane(vc_class &vc,double x,double y,double z,double rsq,int p_id) { - int count=0,i,j,k,lp=up,cp,qp,rp,*stackp(ds),*stackp2(ds2),*dsp; - int us=0,ls=0,qs,iqs,cs,uw,qw,lw; - int *edp,*edd; - double u,l,r,q;bool complicated_setup=false,new_double_edge=false,double_edge=false; + int count=0,i,j,k,lp=up,cp,qp,rp,*stackp(ds),*stackp2(ds2),*dsp; + int us=0,ls=0,qs,iqs,cs,uw,qw,lw; + int *edp,*edd; + double u,l,r,q;bool complicated_setup=false,new_double_edge=false,double_edge=false; - // Initialize the safe testing routine - n_marg=0;px=x;py=y;pz=z;prsq=rsq; + // Initialize the safe testing routine + n_marg=0;px=x;py=y;pz=z;prsq=rsq; - // Test approximately sqrt(n)/4 points for their proximity to the plane - // and keep the one which is closest - uw=m_test(up,u); + // Test approximately sqrt(n)/4 points for their proximity to the plane + // and keep the one which is closest + uw=m_test(up,u); - // Starting from an initial guess, we now move from vertex to vertex, - // to try and find an edge which intersects the cutting plane, - // or a vertex which is on the plane - try { - if(uw==1) { + // Starting from an initial guess, we now move from vertex to vertex, + // to try and find an edge which intersects the cutting plane, + // or a vertex which is on the plane + try { + if(uw==1) { - // The test point is inside the cutting plane. - us=0; - do { - lp=ed[up][us]; - lw=m_test(lp,l); - if(l=p) throw true; - u=l;up=lp; - for(us=0;us=p) throw true; + u=l;up=lp; + for(us=0;us=p) throw true; - u=q;up=qp; - for(us=0;us=p) throw true; + u=q;up=qp; + for(us=0;us=1 - fputs("Bailed out of convex calculation\n",stderr); + fputs("Bailed out of convex calculation\n",stderr); #endif - qw=1;lw=0; - for(qp=0;qp=current_vertex_order) add_memory_vorder(vc); - if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); - vc.n_set_pointer(p,nu[p]); - ed[p]=mep[nu[p]]+((nu[p]<<1)+1)*mec[nu[p]]++; - ed[p][nu[p]<<1]=p; + // Add memory for the new vertex if needed, and + // initialize + while (nu[p]>=current_vertex_order) add_memory_vorder(vc); + if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); + vc.n_set_pointer(p,nu[p]); + ed[p]=mep[nu[p]]+((nu[p]<<1)+1)*mec[nu[p]]++; + ed[p][nu[p]<<1]=p; - // Copy the edges of the original vertex into the new - // one. Delete the edges of the original vertex, and - // update the relational table. - us=cycle_down(i,up); - while(i=current_vertex_order) add_memory_vorder(vc); - if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); + // Add memory to store the vertex if it doesn't exist + // already + k=1; + while(nu[p]>=current_vertex_order) add_memory_vorder(vc); + if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); - // Copy the edges of the original vertex into the new - // one. Delete the edges of the original vertex, and - // update the relational table. - vc.n_set_pointer(p,nu[p]); - ed[p]=mep[nu[p]]+((nu[p]<<1)+1)*mec[nu[p]]++; - ed[p][nu[p]<<1]=p; - us=i++; - while(i0) k+=nu[j]; - } else { - if(j>0) { + // If we're heading into the final part of the + // new facet, then we never worry about the + // duplicate edge calculation. + new_double_edge=false; + if(j>0) k+=nu[j]; + } else { + if(j>0) { - // This vertex was visited before, so - // count those vertices to the ones we - // already have. - k+=nu[j]; + // This vertex was visited before, so + // count those vertices to the ones we + // already have. + k+=nu[j]; - // The only time when we might make a - // duplicate edge is if the point we're - // going to move to next is also a - // marginal point, so test for that - // first. - if(lw==0) { + // The only time when we might make a + // duplicate edge is if the point we're + // going to move to next is also a + // marginal point, so test for that + // first. + if(lw==0) { - // Now see whether this marginal point - // has been visited before. - i=-ed[lp][nu[lp]<<1]; - if(i>0) { + // Now see whether this marginal point + // has been visited before. + i=-ed[lp][nu[lp]<<1]; + if(i>0) { - // Now see if the last edge of that other - // marginal point actually ends up here. - if(ed[i][nu[i]-1]==j) { - new_double_edge=true; - k-=1; - } else new_double_edge=false; - } else { + // Now see if the last edge of that other + // marginal point actually ends up here. + if(ed[i][nu[i]-1]==j) { + new_double_edge=true; + k-=1; + } else new_double_edge=false; + } else { - // That marginal point hasn't been visited - // before, so we probably don't have to worry - // about duplicate edges, except in the - // case when that's the way into the end - // of the facet, because that way always creates - // an edge. - if(j==rp&&lp==up&&ed[qp][nu[qp]+qs]==us) { - new_double_edge=true; - k-=1; - } else new_double_edge=false; - } - } else new_double_edge=false; - } else { + // That marginal point hasn't been visited + // before, so we probably don't have to worry + // about duplicate edges, except in the + // case when that's the way into the end + // of the facet, because that way always creates + // an edge. + if(j==rp&&lp==up&&ed[qp][nu[qp]+qs]==us) { + new_double_edge=true; + k-=1; + } else new_double_edge=false; + } + } else new_double_edge=false; + } else { - // The vertex hasn't been visited - // before, but let's see if it's - // marginal - if(lw==0) { + // The vertex hasn't been visited + // before, but let's see if it's + // marginal + if(lw==0) { - // If it is, we need to check - // for the case that it's a - // small branch, and that we're - // heading right back to where - // we came from - i=-ed[lp][nu[lp]<<1]; - if(i==cp) { - new_double_edge=true; - k-=1; - } else new_double_edge=false; - } else new_double_edge=false; - } - } + // If it is, we need to check + // for the case that it's a + // small branch, and that we're + // heading right back to where + // we came from + i=-ed[lp][nu[lp]<<1]; + if(i==cp) { + new_double_edge=true; + k-=1; + } else new_double_edge=false; + } else new_double_edge=false; + } + } - // k now holds the number of edges of the new vertex - // we are forming. Add memory for it if it doesn't exist - // already. - while(k>=current_vertex_order) add_memory_vorder(vc); - if(mec[k]==mem[k]) add_memory(vc,k,stackp2); + // k now holds the number of edges of the new vertex + // we are forming. Add memory for it if it doesn't exist + // already. + while(k>=current_vertex_order) add_memory_vorder(vc); + if(mec[k]==mem[k]) add_memory(vc,k,stackp2); - // Now create a new vertex with order k, or augment - // the existing one - if(j>0) { + // Now create a new vertex with order k, or augment + // the existing one + if(j>0) { - // If we're augmenting a vertex but we don't - // actually need any more edges, just skip this - // routine to avoid memory confusion - if(nu[j]!=k) { - // Allocate memory and copy the edges - // of the previous instance into it - vc.n_set_aux1(k); - edp=mep[k]+((k<<1)+1)*mec[k]++; - i=0; - while(ids) { - --p; - while(ed[p][nu[p]]==-1) { - j=nu[p]; - edp=ed[p];edd=(mep[j]+((j<<1)+1)*--mec[j]); - while(edpds) { + --p; + while(ed[p][nu[p]]==-1) { + j=nu[p]; + edp=ed[p];edd=(mep[j]+((j<<1)+1)*--mec[j]); + while(edp0) voro_fatal_error("Zero order vertex formed",VOROPP_INTERNAL_ERROR); + // Check for any vertices of zero order + if(*mec>0) voro_fatal_error("Zero order vertex formed",VOROPP_INTERNAL_ERROR); - // Collapse any order 2 vertices and exit - return collapse_order2(vc); + // Collapse any order 2 vertices and exit + return collapse_order2(vc); } /** During the creation of a new facet in the plane routine, it is possible @@ -1078,58 +1078,58 @@ bool voronoicell_base::nplane(vc_class &vc,double x,double y,double z,double rsq * was successful. */ template inline bool voronoicell_base::collapse_order2(vc_class &vc) { - if(!collapse_order1(vc)) return false; - int a,b,i,j,k,l; - while(mec[2]>0) { + if(!collapse_order1(vc)) return false; + int a,b,i,j,k,l; + while(mec[2]>0) { - // Pick a order 2 vertex and read in its edges - i=--mec[2]; - j=mep[2][5*i];k=mep[2][5*i+1]; - if(j==k) { + // Pick a order 2 vertex and read in its edges + i=--mec[2]; + j=mep[2][5*i];k=mep[2][5*i+1]; + if(j==k) { #if VOROPP_VERBOSE >=1 - fputs("Order two vertex joins itself",stderr); + fputs("Order two vertex joins itself",stderr); #endif - return false; - } + return false; + } - // Scan the edges of j to see if joins k - for(l=0;l inline bool voronoicell_base::collapse_order1(vc_class &vc) { - int i,j,k; - while(mec[1]>0) { - up=0; + int i,j,k; + while(mec[1]>0) { + up=0; #if VOROPP_VERBOSE >=1 - fputs("Order one collapse\n",stderr); + fputs("Order one collapse\n",stderr); #endif - i=--mec[1]; - j=mep[1][3*i];k=mep[1][3*i+1]; - i=mep[1][3*i+2]; - if(!delete_connection(vc,j,k,false)) return false; - --p; - if(up==i) up=0; - if(p!=i) { - if(up==p) up=i; - pts[3*i]=pts[3*p]; - pts[3*i+1]=pts[3*p+1]; - pts[3*i+2]=pts[3*p+2]; - for(k=0;k inline bool voronoicell_base::delete_connection(vc_class &vc,int j,int k,bool hand) { - int q=hand?k:cycle_up(k,j); - int i=nu[j]-1,l,*edp,*edd,m; + int q=hand?k:cycle_up(k,j); + int i=nu[j]-1,l,*edp,*edd,m; #if VOROPP_VERBOSE >=1 - if(i<1) { - fputs("Zero order vertex formed\n",stderr); - return false; - } + if(i<1) { + fputs("Zero order vertex formed\n",stderr); + return false; + } #endif - if(mec[i]==mem[i]) add_memory(vc,i,ds2); - vc.n_set_aux1(i); - for(l=0;l &v) { - double area; - v.clear(); - int i,j,k,l,m,n; - double ux,uy,uz,vx,vy,vz,wx,wy,wz; - for(i=1;i=0) { - area=0; - ed[i][j]=-1-k; - l=cycle_up(ed[i][nu[i]+j],k); - m=ed[k][l];ed[k][l]=-1-m; - while(m!=i) { - n=cycle_up(ed[k][nu[k]+l],m); - ux=pts[3*k]-pts[3*i]; - uy=pts[3*k+1]-pts[3*i+1]; - uz=pts[3*k+2]-pts[3*i+2]; - vx=pts[3*m]-pts[3*i]; - vy=pts[3*m+1]-pts[3*i+1]; - vz=pts[3*m+2]-pts[3*i+2]; - wx=uy*vz-uz*vy; - wy=uz*vx-ux*vz; - wz=ux*vy-uy*vx; - area+=sqrt(wx*wx+wy*wy+wz*wz); - k=m;l=n; - m=ed[k][l];ed[k][l]=-1-m; - } - v.push_back(0.125*area); - } - } - reset_edges(); + double area; + v.clear(); + int i,j,k,l,m,n; + double ux,uy,uz,vx,vy,vz,wx,wy,wz; + for(i=1;i=0) { + area=0; + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + m=ed[k][l];ed[k][l]=-1-m; + while(m!=i) { + n=cycle_up(ed[k][nu[k]+l],m); + ux=pts[3*k]-pts[3*i]; + uy=pts[3*k+1]-pts[3*i+1]; + uz=pts[3*k+2]-pts[3*i+2]; + vx=pts[3*m]-pts[3*i]; + vy=pts[3*m+1]-pts[3*i+1]; + vz=pts[3*m+2]-pts[3*i+2]; + wx=uy*vz-uz*vy; + wy=uz*vx-ux*vz; + wz=ux*vy-uy*vx; + area+=sqrt(wx*wx+wy*wy+wz*wz); + k=m;l=n; + m=ed[k][l];ed[k][l]=-1-m; + } + v.push_back(0.125*area); + } + } + reset_edges(); } /** Several routines in the class that gather cell-based statistics internally @@ -1258,11 +1258,11 @@ void voronoicell_base::face_areas(std::vector &v) { * should have already been flipped to negative, and it bails out with an * internal error if it encounters a positive edge. */ inline void voronoicell_base::reset_edges() { - int i,j; - for(i=0;i=0) voro_fatal_error("Edge reset routine found a previously untested edge",VOROPP_INTERNAL_ERROR); - ed[i][j]=-1-ed[i][j]; - } + int i,j; + for(i=0;i=0) voro_fatal_error("Edge reset routine found a previously untested edge",VOROPP_INTERNAL_ERROR); + ed[i][j]=-1-ed[i][j]; + } } /** Checks to see if a given vertex is inside, outside or within the test @@ -1276,16 +1276,16 @@ inline void voronoicell_base::reset_edges() { * \return -1 if the point is inside the plane, 1 if the point is outside the * plane, or 0 if the point is within the plane. */ inline int voronoicell_base::m_test(int n,double &ans) { - double *pp=pts+n+(n<<1); - ans=*(pp++)*px; - ans+=*(pp++)*py; - ans+=*pp*pz-prsq; - if(ans<-tolerance2) { - return -1; - } else if(ans>tolerance2) { - return 1; - } - return check_marginal(n,ans); + double *pp=pts+n+(n<<1); + ans=*(pp++)*px; + ans+=*(pp++)*py; + ans+=*pp*pz-prsq; + if(ans<-tolerance2) { + return -1; + } else if(ans>tolerance2) { + return 1; + } + return check_marginal(n,ans); } /** Checks to see if a given vertex is inside, outside or within the test @@ -1301,23 +1301,23 @@ inline int voronoicell_base::m_test(int n,double &ans) { * \return -1 if the point is inside the plane, 1 if the point is outside the * plane, or 0 if the point is within the plane. */ int voronoicell_base::check_marginal(int n,double &ans) { - int i; - for(i=0;imax_marginal) - voro_fatal_error("Marginal case buffer allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); + int i; + for(i=0;imax_marginal) + voro_fatal_error("Marginal case buffer allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 - fprintf(stderr,"Marginal cases buffer scaled up to %d\n",i); + fprintf(stderr,"Marginal cases buffer scaled up to %d\n",i); #endif - int *pmarg=new int[current_marginal]; - for(int j=0;jtolerance?1:(ans<-tolerance?-1:0); - return marg[n_marg-1]; + int *pmarg=new int[current_marginal]; + for(int j=0;jtolerance?1:(ans<-tolerance?-1:0); + return marg[n_marg-1]; } /** This initializes the class to be a rectangular box. It calls the base class @@ -1328,102 +1328,102 @@ int voronoicell_base::check_marginal(int n,double &ans) { * \param[in] (ymin,ymax) the minimum and maximum y coordinates. * \param[in] (zmin,zmax) the minimum and maximum z coordinates. */ void voronoicell_neighbor::init(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax) { - init_base(xmin,xmax,ymin,ymax,zmin,zmax); - int *q=mne[3]; - *q=-5;q[1]=-3;q[2]=-1; - q[3]=-5;q[4]=-2;q[5]=-3; - q[6]=-5;q[7]=-1;q[8]=-4; - q[9]=-5;q[10]=-4;q[11]=-2; - q[12]=-6;q[13]=-1;q[14]=-3; - q[15]=-6;q[16]=-3;q[17]=-2; - q[18]=-6;q[19]=-4;q[20]=-1; - q[21]=-6;q[22]=-2;q[23]=-4; - *ne=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9; - ne[4]=q+12;ne[5]=q+15;ne[6]=q+18;ne[7]=q+21; + init_base(xmin,xmax,ymin,ymax,zmin,zmax); + int *q=mne[3]; + *q=-5;q[1]=-3;q[2]=-1; + q[3]=-5;q[4]=-2;q[5]=-3; + q[6]=-5;q[7]=-1;q[8]=-4; + q[9]=-5;q[10]=-4;q[11]=-2; + q[12]=-6;q[13]=-1;q[14]=-3; + q[15]=-6;q[16]=-3;q[17]=-2; + q[18]=-6;q[19]=-4;q[20]=-1; + q[21]=-6;q[22]=-2;q[23]=-4; + *ne=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9; + ne[4]=q+12;ne[5]=q+15;ne[6]=q+18;ne[7]=q+21; } /** This routine checks to make sure the neighbor information of each face is * consistent. */ void voronoicell_neighbor::check_facets() { - int i,j,k,l,m,q; - for(i=1;i=0) { - ed[i][j]=-1-k; - q=ne[i][j]; - l=cycle_up(ed[i][nu[i]+j],k); - do { - m=ed[k][l]; - ed[k][l]=-1-m; - if(ne[k][l]!=q) fprintf(stderr,"Facet error at (%d,%d)=%d, started from (%d,%d)=%d\n",k,l,ne[k][l],i,j,q); - l=cycle_up(ed[k][nu[k]+l],m); - k=m; - } while (k!=i); - } - } - reset_edges(); + int i,j,k,l,m,q; + for(i=1;i=0) { + ed[i][j]=-1-k; + q=ne[i][j]; + l=cycle_up(ed[i][nu[i]+j],k); + do { + m=ed[k][l]; + ed[k][l]=-1-m; + if(ne[k][l]!=q) fprintf(stderr,"Facet error at (%d,%d)=%d, started from (%d,%d)=%d\n",k,l,ne[k][l],i,j,q); + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); + } + } + reset_edges(); } /** The class constructor allocates memory for storing neighbor information. */ voronoicell_neighbor::voronoicell_neighbor() { - int i; - mne=new int*[current_vertex_order]; - ne=new int*[current_vertices]; - for(i=0;i<3;i++) mne[i]=new int[init_n_vertices*i]; - mne[3]=new int[init_3_vertices*3]; - for(i=4;i=0;i--) if(mem[i]>0) delete [] mne[i]; - delete [] mne; - delete [] ne; + for(int i=current_vertex_order-1;i>=0;i--) if(mem[i]>0) delete [] mne[i]; + delete [] mne; + delete [] ne; } /** Computes a vector list of neighbors. */ void voronoicell_neighbor::neighbors(std::vector &v) { - v.clear(); - int i,j,k,l,m; - for(i=1;i=0) { - v.push_back(ne[i][j]); - ed[i][j]=-1-k; - l=cycle_up(ed[i][nu[i]+j],k); - do { - m=ed[k][l]; - ed[k][l]=-1-m; - l=cycle_up(ed[k][nu[k]+l],m); - k=m; - } while (k!=i); - } - } - reset_edges(); + v.clear(); + int i,j,k,l,m; + for(i=1;i=0) { + v.push_back(ne[i][j]); + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + do { + m=ed[k][l]; + ed[k][l]=-1-m; + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); + } + } + reset_edges(); } /** Returns the number of faces of a computed Voronoi cell. * \return The number of faces. */ int voronoicell_base::number_of_faces() { - int i,j,k,l,m,s=0; - for(i=1;i=0) { - s++; - ed[i][j]=-1-k; - l=cycle_up(ed[i][nu[i]+j],k); - do { - m=ed[k][l]; - ed[k][l]=-1-m; - l=cycle_up(ed[k][nu[k]+l],m); - k=m; - } while (k!=i); + int i,j,k,l,m,s=0; + for(i=1;i=0) { + s++; + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + do { + m=ed[k][l]; + ed[k][l]=-1-m; + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); - } - } - reset_edges(); - return s; + } + } + reset_edges(); + return s; } /** Returns a vector of the vertex vectors in the global coordinate system. @@ -1431,41 +1431,41 @@ int voronoicell_base::number_of_faces() { * \param[in] (x,y,z) the position vector of the particle in the global * coordinate system. */ void voronoicell_base::vertices(double x,double y,double z,std::vector &v) { - v.resize(3*p); - double *ptsp=pts; - for(int i=0;i<3*p;i+=3) { - v[i]=x+*(ptsp++)*0.5; - v[i+1]=y+*(ptsp++)*0.5; - v[i+2]=z+*(ptsp++)*0.5; - } + v.resize(3*p); + double *ptsp=pts; + for(int i=0;i<3*p;i+=3) { + v[i]=x+*(ptsp++)*0.5; + v[i+1]=y+*(ptsp++)*0.5; + v[i+2]=z+*(ptsp++)*0.5; + } } /** For each face, this routine outputs a bracketed sequence of numbers * containing a list of all the vertices that make up that face. * \param[out] v the vector to store the results in. */ void voronoicell_base::face_vertices(std::vector &v) { - int i,j,k,l,m,vp(0),vn; - v.clear(); - for(i=1;i=0) { - v.push_back(0); - v.push_back(i); - ed[i][j]=-1-k; - l=cycle_up(ed[i][nu[i]+j],k); - do { - v.push_back(k); - m=ed[k][l]; - ed[k][l]=-1-m; - l=cycle_up(ed[k][nu[k]+l],m); - k=m; - } while (k!=i); - vn=v.size(); - v[vp]=vn-vp-1; - vp=vn; - } - } - reset_edges(); + int i,j,k,l,m,vp(0),vn; + v.clear(); + for(i=1;i=0) { + v.push_back(0); + v.push_back(i); + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + do { + v.push_back(k); + m=ed[k][l]; + ed[k][l]=-1-m; + l=cycle_up(ed[k][nu[k]+l],m); + k=m; + } while (k!=i); + vn=v.size(); + v[vp]=vn-vp-1; + vp=vn; + } + } + reset_edges(); } // Explicit instantiation diff --git a/src/USER-PTM/ptm_voronoi_cell.h b/src/USER-PTM/ptm_voronoi_cell.h index 8137aa3340..eb091dd36b 100644 --- a/src/USER-PTM/ptm_voronoi_cell.h +++ b/src/USER-PTM/ptm_voronoi_cell.h @@ -76,180 +76,180 @@ namespace ptm_voro { * voronoicell and voronoicell_neighbor classes, which extend it based on * whether neighboring particle ID information needs to be tracked. */ class voronoicell_base { - public: - /** This holds the current size of the arrays ed and nu, which - * hold the vertex information. If more vertices are created - * than can fit in this array, then it is dynamically extended - * using the add_memory_vertices routine. */ - int current_vertices; - /** This holds the current maximum allowed order of a vertex, - * which sets the size of the mem, mep, and mec arrays. If a - * vertex is created with more vertices than this, the arrays - * are dynamically extended using the add_memory_vorder routine. - */ - int current_vertex_order; - /** This sets the size of the main delete stack. */ - int current_delete_size; - /** This sets the size of the auxiliary delete stack. */ - int current_delete2_size; - /** This sets the total number of vertices in the current cell. - */ - int p; - /** This is the index of particular point in the cell, which is - * used to start the tracing routines for plane intersection - * and cutting. These routines will work starting from any - * point, but it's often most efficient to start from the last - * point considered, since in many cases, the cell construction - * algorithm may consider many planes with similar vectors - * concurrently. */ - int up; - /** This is a two dimensional array that holds information - * about the edge connections of the vertices that make up the - * cell. The two dimensional array is not allocated in the - * usual method. To account for the fact the different vertices - * have different orders, and thus require different amounts of - * storage, the elements of ed[i] point to one-dimensional - * arrays in the mep[] array of different sizes. - * - * More specifically, if vertex i has order m, then ed[i] - * points to a one-dimensional array in mep[m] that has 2*m+1 - * entries. The first m elements hold the neighboring edges, so - * that the jth edge of vertex i is held in ed[i][j]. The next - * m elements hold a table of relations which is redundant but - * helps speed up the computation. It satisfies the relation - * ed[ed[i][j]][ed[i][m+j]]=i. The final entry holds a back - * pointer, so that ed[i+2*m]=i. The back pointers are used - * when rearranging the memory. */ - int **ed; - /** This array holds the order of the vertices in the Voronoi - * cell. This array is dynamically allocated, with its current - * size held by current_vertices. */ - int *nu; - /** This in an array with size 3*current_vertices for holding - * the positions of the vertices. */ - double *pts; - voronoicell_base(); - virtual ~voronoicell_base(); - void init_base(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); - void init_octahedron_base(double l); - void init_tetrahedron_base(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3); - void translate(double x,double y,double z); - double volume(); - double max_radius_squared(); - double total_edge_distance(); - double surface_area(); - void centroid(double &cx,double &cy,double &cz); - int number_of_faces(); - int number_of_edges(); - void vertex_orders(std::vector &v); - void vertices(std::vector &v); - void vertices(double x,double y,double z,std::vector &v); - void face_areas(std::vector &v); - void face_orders(std::vector &v); - void face_freq_table(std::vector &v); - void face_vertices(std::vector &v); - void face_perimeters(std::vector &v); - void normals(std::vector &v); - template - bool nplane(vc_class &vc,double x,double y,double z,double rsq,int p_id); - bool plane_intersects(double x,double y,double z,double rsq); - bool plane_intersects_guess(double x,double y,double z,double rsq); - void construct_relations(); - void check_relations(); - void check_duplicates(); - /** Returns a list of IDs of neighboring particles - * corresponding to each face. - * \param[out] v a reference to a vector in which to return the - * results. If no neighbor information is - * available, a blank vector is returned. */ - virtual void neighbors(std::vector &v) {v.clear();} - /** This a virtual function that is overridden by a routine to - * print the neighboring particle IDs for a given vertex. By - * default, when no neighbor information is available, the - * routine does nothing. - * \param[in] i the vertex to consider. */ - /** This is a simple inline function for picking out the index - * of the next edge counterclockwise at the current vertex. - * \param[in] a the index of an edge of the current vertex. - * \param[in] p the number of the vertex. - * \return 0 if a=nu[p]-1, or a+1 otherwise. */ - inline int cycle_up(int a,int p) {return a==nu[p]-1?0:a+1;} - /** This is a simple inline function for picking out the index - * of the next edge clockwise from the current vertex. - * \param[in] a the index of an edge of the current vertex. - * \param[in] p the number of the vertex. - * \return nu[p]-1 if a=0, or a-1 otherwise. */ - inline int cycle_down(int a,int p) {return a==0?nu[p]-1:a-1;} - protected: - /** This a one dimensional array that holds the current sizes - * of the memory allocations for them mep array.*/ - int *mem; - /** This is a one dimensional array that holds the current - * number of vertices of order p that are stored in the mep[p] - * array. */ - int *mec; - /** This is a two dimensional array for holding the information - * about the edges of the Voronoi cell. mep[p] is a - * one-dimensional array for holding the edge information about - * all vertices of order p, with each vertex holding 2*p+1 - * integers of information. The total number of vertices held - * on mep[p] is stored in mem[p]. If the space runs out, the - * code allocates more using the add_memory() routine. */ - int **mep; - inline void reset_edges(); - template - void check_memory_for_copy(vc_class &vc,voronoicell_base* vb); - void copy(voronoicell_base* vb); - private: - /** This is the delete stack, used to store the vertices which - * are going to be deleted during the plane cutting procedure. - */ - int *ds,*stacke; - /** This is the auxiliary delete stack, which has size set by - * current_delete2_size. */ - int *ds2,*stacke2; - /** This stores the current memory allocation for the marginal - * cases. */ - int current_marginal; - /** This stores the total number of marginal points which are - * currently in the buffer. */ - int n_marg; - /** This array contains a list of the marginal points, and also - * the outcomes of the marginal tests. */ - int *marg; - /** The x coordinate of the normal vector to the test plane. */ - double px; - /** The y coordinate of the normal vector to the test plane. */ - double py; - /** The z coordinate of the normal vector to the test plane. */ - double pz; - /** The magnitude of the normal vector to the test plane. */ - double prsq; - template - void add_memory(vc_class &vc,int i,int *stackp2); - template - void add_memory_vertices(vc_class &vc); - template - void add_memory_vorder(vc_class &vc); - void add_memory_ds(int *&stackp); - void add_memory_ds2(int *&stackp2); - template - inline bool collapse_order1(vc_class &vc); - template - inline bool collapse_order2(vc_class &vc); - template - inline bool delete_connection(vc_class &vc,int j,int k,bool hand); - template - inline bool search_for_outside_edge(vc_class &vc,int &up); - template - inline void add_to_stack(vc_class &vc,int lp,int *&stackp2); - inline bool plane_intersects_track(double x,double y,double z,double rs,double g); - inline void normals_search(std::vector &v,int i,int j,int k); - inline bool search_edge(int l,int &m,int &k); - inline int m_test(int n,double &ans); - int check_marginal(int n,double &ans); - friend class voronoicell; - friend class voronoicell_neighbor; + public: + /** This holds the current size of the arrays ed and nu, which + * hold the vertex information. If more vertices are created + * than can fit in this array, then it is dynamically extended + * using the add_memory_vertices routine. */ + int current_vertices; + /** This holds the current maximum allowed order of a vertex, + * which sets the size of the mem, mep, and mec arrays. If a + * vertex is created with more vertices than this, the arrays + * are dynamically extended using the add_memory_vorder routine. + */ + int current_vertex_order; + /** This sets the size of the main delete stack. */ + int current_delete_size; + /** This sets the size of the auxiliary delete stack. */ + int current_delete2_size; + /** This sets the total number of vertices in the current cell. + */ + int p; + /** This is the index of particular point in the cell, which is + * used to start the tracing routines for plane intersection + * and cutting. These routines will work starting from any + * point, but it's often most efficient to start from the last + * point considered, since in many cases, the cell construction + * algorithm may consider many planes with similar vectors + * concurrently. */ + int up; + /** This is a two dimensional array that holds information + * about the edge connections of the vertices that make up the + * cell. The two dimensional array is not allocated in the + * usual method. To account for the fact the different vertices + * have different orders, and thus require different amounts of + * storage, the elements of ed[i] point to one-dimensional + * arrays in the mep[] array of different sizes. + * + * More specifically, if vertex i has order m, then ed[i] + * points to a one-dimensional array in mep[m] that has 2*m+1 + * entries. The first m elements hold the neighboring edges, so + * that the jth edge of vertex i is held in ed[i][j]. The next + * m elements hold a table of relations which is redundant but + * helps speed up the computation. It satisfies the relation + * ed[ed[i][j]][ed[i][m+j]]=i. The final entry holds a back + * pointer, so that ed[i+2*m]=i. The back pointers are used + * when rearranging the memory. */ + int **ed; + /** This array holds the order of the vertices in the Voronoi + * cell. This array is dynamically allocated, with its current + * size held by current_vertices. */ + int *nu; + /** This in an array with size 3*current_vertices for holding + * the positions of the vertices. */ + double *pts; + voronoicell_base(); + virtual ~voronoicell_base(); + void init_base(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); + void init_octahedron_base(double l); + void init_tetrahedron_base(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3); + void translate(double x,double y,double z); + double volume(); + double max_radius_squared(); + double total_edge_distance(); + double surface_area(); + void centroid(double &cx,double &cy,double &cz); + int number_of_faces(); + int number_of_edges(); + void vertex_orders(std::vector &v); + void vertices(std::vector &v); + void vertices(double x,double y,double z,std::vector &v); + void face_areas(std::vector &v); + void face_orders(std::vector &v); + void face_freq_table(std::vector &v); + void face_vertices(std::vector &v); + void face_perimeters(std::vector &v); + void normals(std::vector &v); + template + bool nplane(vc_class &vc,double x,double y,double z,double rsq,int p_id); + bool plane_intersects(double x,double y,double z,double rsq); + bool plane_intersects_guess(double x,double y,double z,double rsq); + void construct_relations(); + void check_relations(); + void check_duplicates(); + /** Returns a list of IDs of neighboring particles + * corresponding to each face. + * \param[out] v a reference to a vector in which to return the + * results. If no neighbor information is + * available, a blank vector is returned. */ + virtual void neighbors(std::vector &v) {v.clear();} + /** This a virtual function that is overridden by a routine to + * print the neighboring particle IDs for a given vertex. By + * default, when no neighbor information is available, the + * routine does nothing. + * \param[in] i the vertex to consider. */ + /** This is a simple inline function for picking out the index + * of the next edge counterclockwise at the current vertex. + * \param[in] a the index of an edge of the current vertex. + * \param[in] p the number of the vertex. + * \return 0 if a=nu[p]-1, or a+1 otherwise. */ + inline int cycle_up(int a,int p) {return a==nu[p]-1?0:a+1;} + /** This is a simple inline function for picking out the index + * of the next edge clockwise from the current vertex. + * \param[in] a the index of an edge of the current vertex. + * \param[in] p the number of the vertex. + * \return nu[p]-1 if a=0, or a-1 otherwise. */ + inline int cycle_down(int a,int p) {return a==0?nu[p]-1:a-1;} + protected: + /** This a one dimensional array that holds the current sizes + * of the memory allocations for them mep array.*/ + int *mem; + /** This is a one dimensional array that holds the current + * number of vertices of order p that are stored in the mep[p] + * array. */ + int *mec; + /** This is a two dimensional array for holding the information + * about the edges of the Voronoi cell. mep[p] is a + * one-dimensional array for holding the edge information about + * all vertices of order p, with each vertex holding 2*p+1 + * integers of information. The total number of vertices held + * on mep[p] is stored in mem[p]. If the space runs out, the + * code allocates more using the add_memory() routine. */ + int **mep; + inline void reset_edges(); + template + void check_memory_for_copy(vc_class &vc,voronoicell_base* vb); + void copy(voronoicell_base* vb); + private: + /** This is the delete stack, used to store the vertices which + * are going to be deleted during the plane cutting procedure. + */ + int *ds,*stacke; + /** This is the auxiliary delete stack, which has size set by + * current_delete2_size. */ + int *ds2,*stacke2; + /** This stores the current memory allocation for the marginal + * cases. */ + int current_marginal; + /** This stores the total number of marginal points which are + * currently in the buffer. */ + int n_marg; + /** This array contains a list of the marginal points, and also + * the outcomes of the marginal tests. */ + int *marg; + /** The x coordinate of the normal vector to the test plane. */ + double px; + /** The y coordinate of the normal vector to the test plane. */ + double py; + /** The z coordinate of the normal vector to the test plane. */ + double pz; + /** The magnitude of the normal vector to the test plane. */ + double prsq; + template + void add_memory(vc_class &vc,int i,int *stackp2); + template + void add_memory_vertices(vc_class &vc); + template + void add_memory_vorder(vc_class &vc); + void add_memory_ds(int *&stackp); + void add_memory_ds2(int *&stackp2); + template + inline bool collapse_order1(vc_class &vc); + template + inline bool collapse_order2(vc_class &vc); + template + inline bool delete_connection(vc_class &vc,int j,int k,bool hand); + template + inline bool search_for_outside_edge(vc_class &vc,int &up); + template + inline void add_to_stack(vc_class &vc,int lp,int *&stackp2); + inline bool plane_intersects_track(double x,double y,double z,double rs,double g); + inline void normals_search(std::vector &v,int i,int j,int k); + inline bool search_edge(int l,int &m,int &k); + inline int m_test(int n,double &ans); + int check_marginal(int n,double &ans); + friend class voronoicell; + friend class voronoicell_neighbor; }; /** \brief Extension of the voronoicell_base class to represent a Voronoi cell @@ -260,105 +260,105 @@ class voronoicell_base { * It contains additional data structures mne and ne for storing this * information. */ class voronoicell_neighbor : public voronoicell_base { - public: - using voronoicell_base::nplane; - /** This two dimensional array holds the neighbor information - * associated with each vertex. mne[p] is a one dimensional - * array which holds all of the neighbor information for - * vertices of order p. */ - int **mne; - /** This is a two dimensional array that holds the neighbor - * information associated with each vertex. ne[i] points to a - * one-dimensional array in mne[nu[i]]. ne[i][j] holds the - * neighbor information associated with the jth edge of vertex - * i. It is set to the ID number of the plane that made the - * face that is clockwise from the jth edge. */ - int **ne; - voronoicell_neighbor(); - ~voronoicell_neighbor(); - void operator=(voronoicell_neighbor &c); - /** Cuts the Voronoi cell by a particle whose center is at a - * separation of (x,y,z) from the cell center. The value of rsq - * should be initially set to \f$x^2+y^2+z^2\f$. - * \param[in] (x,y,z) the normal vector to the plane. - * \param[in] rsq the distance along this vector of the plane. - * \param[in] p_id the plane ID (for neighbor tracking only). - * \return False if the plane cut deleted the cell entirely, - * true otherwise. */ - inline bool nplane(double x,double y,double z,double rsq,int p_id) { - return nplane(*this,x,y,z,rsq,p_id); - } - /** This routine calculates the modulus squared of the vector - * before passing it to the main nplane() routine with full - * arguments. - * \param[in] (x,y,z) the vector to cut the cell by. - * \param[in] p_id the plane ID (for neighbor tracking only). - * \return False if the plane cut deleted the cell entirely, - * true otherwise. */ - inline bool nplane(double x,double y,double z,int p_id) { - double rsq=x*x+y*y+z*z; - return nplane(*this,x,y,z,rsq,p_id); - } - /** This version of the plane routine just makes up the plane - * ID to be zero. It will only be referenced if neighbor - * tracking is enabled. - * \param[in] (x,y,z) the vector to cut the cell by. - * \param[in] rsq the modulus squared of the vector. - * \return False if the plane cut deleted the cell entirely, - * true otherwise. */ - inline bool plane(double x,double y,double z,double rsq) { - return nplane(*this,x,y,z,rsq,0); - } - /** Cuts a Voronoi cell using the influence of a particle at - * (x,y,z), first calculating the modulus squared of this - * vector before passing it to the main nplane() routine. Zero - * is supplied as the plane ID, which will be ignored unless - * neighbor tracking is enabled. - * \param[in] (x,y,z) the vector to cut the cell by. - * \return False if the plane cut deleted the cell entirely, - * true otherwise. */ - inline bool plane(double x,double y,double z) { - double rsq=x*x+y*y+z*z; - return nplane(*this,x,y,z,rsq,0); - } - void init(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); - void check_facets(); - virtual void neighbors(std::vector &v); + public: + using voronoicell_base::nplane; + /** This two dimensional array holds the neighbor information + * associated with each vertex. mne[p] is a one dimensional + * array which holds all of the neighbor information for + * vertices of order p. */ + int **mne; + /** This is a two dimensional array that holds the neighbor + * information associated with each vertex. ne[i] points to a + * one-dimensional array in mne[nu[i]]. ne[i][j] holds the + * neighbor information associated with the jth edge of vertex + * i. It is set to the ID number of the plane that made the + * face that is clockwise from the jth edge. */ + int **ne; + voronoicell_neighbor(); + ~voronoicell_neighbor(); + void operator=(voronoicell_neighbor &c); + /** Cuts the Voronoi cell by a particle whose center is at a + * separation of (x,y,z) from the cell center. The value of rsq + * should be initially set to \f$x^2+y^2+z^2\f$. + * \param[in] (x,y,z) the normal vector to the plane. + * \param[in] rsq the distance along this vector of the plane. + * \param[in] p_id the plane ID (for neighbor tracking only). + * \return False if the plane cut deleted the cell entirely, + * true otherwise. */ + inline bool nplane(double x,double y,double z,double rsq,int p_id) { + return nplane(*this,x,y,z,rsq,p_id); + } + /** This routine calculates the modulus squared of the vector + * before passing it to the main nplane() routine with full + * arguments. + * \param[in] (x,y,z) the vector to cut the cell by. + * \param[in] p_id the plane ID (for neighbor tracking only). + * \return False if the plane cut deleted the cell entirely, + * true otherwise. */ + inline bool nplane(double x,double y,double z,int p_id) { + double rsq=x*x+y*y+z*z; + return nplane(*this,x,y,z,rsq,p_id); + } + /** This version of the plane routine just makes up the plane + * ID to be zero. It will only be referenced if neighbor + * tracking is enabled. + * \param[in] (x,y,z) the vector to cut the cell by. + * \param[in] rsq the modulus squared of the vector. + * \return False if the plane cut deleted the cell entirely, + * true otherwise. */ + inline bool plane(double x,double y,double z,double rsq) { + return nplane(*this,x,y,z,rsq,0); + } + /** Cuts a Voronoi cell using the influence of a particle at + * (x,y,z), first calculating the modulus squared of this + * vector before passing it to the main nplane() routine. Zero + * is supplied as the plane ID, which will be ignored unless + * neighbor tracking is enabled. + * \param[in] (x,y,z) the vector to cut the cell by. + * \return False if the plane cut deleted the cell entirely, + * true otherwise. */ + inline bool plane(double x,double y,double z) { + double rsq=x*x+y*y+z*z; + return nplane(*this,x,y,z,rsq,0); + } + void init(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); + void check_facets(); + virtual void neighbors(std::vector &v); - private: - int *paux1; - int *paux2; - inline void n_allocate(int i,int m) {mne[i]=new int[m*i];} - inline void n_add_memory_vertices(int i) { - int **pp=new int*[i]; - for(int j=0;j Date: Sat, 16 Feb 2019 13:42:38 -0500 Subject: [PATCH 7/9] use c++ style include files throughout --- src/USER-PTM/ptm_canonical_coloured.cpp | 2 +- src/USER-PTM/ptm_convex_hull_incremental.cpp | 2 +- src/USER-PTM/ptm_graph_tools.cpp | 2 +- src/USER-PTM/ptm_index.cpp | 2 +- src/USER-PTM/ptm_initialize_data.cpp | 2 +- src/USER-PTM/ptm_polar.cpp | 2 +- src/USER-PTM/ptm_quat.cpp | 2 +- src/USER-PTM/ptm_structure_matcher.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/USER-PTM/ptm_canonical_coloured.cpp b/src/USER-PTM/ptm_canonical_coloured.cpp index 4c794bd9ca..86c3f90b3b 100644 --- a/src/USER-PTM/ptm_canonical_coloured.cpp +++ b/src/USER-PTM/ptm_canonical_coloured.cpp @@ -7,7 +7,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include #include "ptm_graph_tools.h" diff --git a/src/USER-PTM/ptm_convex_hull_incremental.cpp b/src/USER-PTM/ptm_convex_hull_incremental.cpp index fb0c95201b..45643ec515 100644 --- a/src/USER-PTM/ptm_convex_hull_incremental.cpp +++ b/src/USER-PTM/ptm_convex_hull_incremental.cpp @@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include +#include #include #include #include "ptm_convex_hull_incremental.h" diff --git a/src/USER-PTM/ptm_graph_tools.cpp b/src/USER-PTM/ptm_graph_tools.cpp index 0944b6992c..a2dbd1719f 100644 --- a/src/USER-PTM/ptm_graph_tools.cpp +++ b/src/USER-PTM/ptm_graph_tools.cpp @@ -7,7 +7,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include "ptm_graph_tools.h" #include "ptm_constants.h" diff --git a/src/USER-PTM/ptm_index.cpp b/src/USER-PTM/ptm_index.cpp index 26ccd6a32f..3068e7a7f6 100644 --- a/src/USER-PTM/ptm_index.cpp +++ b/src/USER-PTM/ptm_index.cpp @@ -25,7 +25,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include +#include static double calculate_interatomic_distance(int type, double scale) { assert(type >= 1 && type <= 8); diff --git a/src/USER-PTM/ptm_initialize_data.cpp b/src/USER-PTM/ptm_initialize_data.cpp index 49fbb8a0fe..49dc6f2323 100644 --- a/src/USER-PTM/ptm_initialize_data.cpp +++ b/src/USER-PTM/ptm_initialize_data.cpp @@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include +#include #include #include #include diff --git a/src/USER-PTM/ptm_polar.cpp b/src/USER-PTM/ptm_polar.cpp index f80224f84c..7a2695b504 100644 --- a/src/USER-PTM/ptm_polar.cpp +++ b/src/USER-PTM/ptm_polar.cpp @@ -87,7 +87,7 @@ #include #include -#include +#include #include "ptm_quat.h" diff --git a/src/USER-PTM/ptm_quat.cpp b/src/USER-PTM/ptm_quat.cpp index 1fcdf7e0a1..4a93499b3a 100644 --- a/src/USER-PTM/ptm_quat.cpp +++ b/src/USER-PTM/ptm_quat.cpp @@ -7,7 +7,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include #include diff --git a/src/USER-PTM/ptm_structure_matcher.cpp b/src/USER-PTM/ptm_structure_matcher.cpp index 63bcfade67..d50676a3c1 100644 --- a/src/USER-PTM/ptm_structure_matcher.cpp +++ b/src/USER-PTM/ptm_structure_matcher.cpp @@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include +#include #include #include #include From d5fd423496c4d18c7710f37fd5684ed17b102f9b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 16 Feb 2019 13:52:40 -0500 Subject: [PATCH 8/9] silence compiler warnings --- src/USER-PTM/compute_ptm_atom.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/USER-PTM/compute_ptm_atom.cpp b/src/USER-PTM/compute_ptm_atom.cpp index 270f6f0079..7460d7c2f0 100644 --- a/src/USER-PTM/compute_ptm_atom.cpp +++ b/src/USER-PTM/compute_ptm_atom.cpp @@ -154,7 +154,7 @@ void ComputePTMAtom::init() { /* ---------------------------------------------------------------------- */ -void ComputePTMAtom::init_list(int id, NeighList *ptr) { list = ptr; } +void ComputePTMAtom::init_list(int /* id */, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ @@ -266,7 +266,6 @@ void ComputePTMAtom::compute_peratom() { double **x = atom->x; int *mask = atom->mask; - int nlocal = atom->nlocal; ptmnbrdata_t nbrlist = {x, numneigh, firstneigh, ilist, atom->nlocal}; for (int ii = 0; ii < inum; ii++) { From f0a410aa963dee4914d06377d16f8641aa5036cd Mon Sep 17 00:00:00 2001 From: pmla Date: Sun, 17 Feb 2019 23:17:37 -0500 Subject: [PATCH 9/9] replaced manual allocation with std::vector --- src/USER-PTM/compute_ptm_atom.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/USER-PTM/compute_ptm_atom.cpp b/src/USER-PTM/compute_ptm_atom.cpp index 7460d7c2f0..41e6540b97 100644 --- a/src/USER-PTM/compute_ptm_atom.cpp +++ b/src/USER-PTM/compute_ptm_atom.cpp @@ -20,6 +20,7 @@ under #include #include #include +#include #include "atom.h" #include "comm.h" @@ -174,7 +175,6 @@ typedef struct { double d; } ptmnbr_t; - static bool sorthelper_compare(ptmnbr_t const &a, ptmnbr_t const &b) { return a.d < b.d; } @@ -197,9 +197,8 @@ static int get_neighbours(void* vdata, size_t central_index, size_t atom_index, jnum = data->numneigh[central_index]; } - ptmnbr_t *nbr_order = new ptmnbr_t[jnum]; + std::vector nbr_order; - int count = 0; for (int jj = 0; jj < jnum; jj++) { int j = jlist[jj]; j &= NEIGHMASK; @@ -211,13 +210,12 @@ static int get_neighbours(void* vdata, size_t central_index, size_t atom_index, double dz = pos[2] - x[j][2]; double rsq = dx * dx + dy * dy + dz * dz; - nbr_order[count].index = j; - nbr_order[count].d = rsq; - count++; + ptmnbr_t nbr = {j, rsq}; + nbr_order.push_back(nbr); } - std::sort(nbr_order, nbr_order + count, &sorthelper_compare); - int num_nbrs = std::min(num - 1, count); + std::sort(nbr_order.begin(), nbr_order.end(), &sorthelper_compare); + int num_nbrs = std::min(num - 1, (int)nbr_order.size()); nbr_pos[0][0] = nbr_pos[0][1] = nbr_pos[0][2] = 0; nbr_indices[0] = atom_index; @@ -233,7 +231,6 @@ static int get_neighbours(void* vdata, size_t central_index, size_t atom_index, numbers[jj + 1] = 0; } - delete[] nbr_order; return num_nbrs + 1; }