# SymGen

0 ? 1 : -1) : 0; } //PHP doesn't always get the exact value right because it can only store so many decimal places //this cheecky function establishes if an answer is nearly right and, if it is, rounds to to the nearby correct value function exactify(\$x) { \$vals = array(1, 0, 2, 3, 0.5, sqrt(2), M_PI); foreach (\$vals as \$val) { if(abs(\$x - \$val) < 1e-6) { return \$val; } elseif(abs(\$val + \$x) < 1e-6) { return -\$val; } } return \$x; } //define your symmetry operations, the HTML to render them and their type (in Schoenflies) //identity \$type['E'] = 'identity'; \$operations['1'] = array ( 1, 0, 0, 0, 1, 0, 0, 0, 1); \$operations['1']['html'] = '1'; \$operations['1']['type'] = 'E'; //inversion \$type['i'] = 'inversion'; \$operations['-1'] = array (-1, 0, 0, 0, -1, 0, 0, 0, -1); \$operations['-1']['html'] = '1'; \$operations['-1']['type'] = 'i'; //reflection \$type['sigma'] = 'reflection'; \$planes = array ( array(1,0,0), //m_x array(0,1,0), //m_y array(0,0,1), //m_z array(1,1,0), //etc array(1,0,1), array(0,1,1), array(-1,1,0), array(-1,0,1), array(0,1,-1) ); foreach(\$planes as \$plane) { \$operations['m'.\$plane[0].\$plane[1].\$plane[2]] = array (-pow(\$plane[0],2)+pow(\$plane[1],2)+pow(\$plane[2],2), -2*\$plane[0]*\$plane[1], -2*\$plane[0]*\$plane[2], -2*\$plane[1]*\$plane[0], -pow(\$plane[1],2)+pow(\$plane[0],2)+pow(\$plane[2],2), -2*\$plane[1]*\$plane[2], -2*\$plane[2]*\$plane[0], -2*\$plane[2]*\$plane[1], -pow(\$plane[2],2)+pow(\$plane[0],2)+pow(\$plane[1],2) ); //go through and divide by the modulus for(\$i = 0; \$i < 9; \$i++) { \$operations['m'.\$plane[0].\$plane[1].\$plane[2]][\$i] = \$operations['m'.\$plane[0].\$plane[1].\$plane[2]][\$i] / (pow(\$plane[0],2)+pow(\$plane[1],2)+pow(\$plane[2],2)); exactify(\$operations['m'.\$plane[0].\$plane[1].\$plane[2]][\$i]);} \$operations['m'.\$plane[0].\$plane[1].\$plane[2]]['html'] = 'm['.(\$plane[0] >= 0 ? \$plane[0] : ''.abs(\$plane[0]).'').(\$plane[1] >= 0 ? \$plane[1] : ''.abs(\$plane[1]).'').(\$plane[2] >= 0 ? \$plane[2] : ''.abs(\$plane[2]).'').']'; \$operations['m'.\$plane[0].\$plane[1].\$plane[2]]['type'] = 'sigma'; /* 1 / (Px2 + Py2 + Pz2)* ... -Px2 + Pz* Pz + Py* Py - 2 * Px * Py - 2 * Px * Pz - 2 * Py * Px -Py2 + Px*Px + Pz*Pz - 2 * Py * Pz - 2 * Pz * Px -2 * Pz * Py -Pz2 + Py*Py + Px*Px where Px, Py, Pz is the normal vector (see http://www.euclideanspace.com/maths/geometry/affine/reflection/index.htm )*/ } //proper rotation \$type['C2'] = 'proper rotation (order 2)'; \$type['C3'] = 'proper rotation (order 3)'; \$type['C4'] = 'proper rotation (order 4)'; \$type['C6'] = 'proper rotation (order 6)'; \$axes = array ( array(1,0,0), //m_x array(0,1,0), //m_y array(0,0,1), //m_z array(1,1,0), //etc array(1,0,1), array(0,1,1), array(-1,1,0), array(1,1,1), array(-1,1,1), array(1,-1,1), array(1,1,-1), array(-1,-1,1), array(-1,1,-1), array(1,-1,-1), array(-1,-1,-1) ); \$orders = array(2,3,4); //999 add 6 again later foreach(\$orders as \$order) { for(\$repeat = 1; \$repeat < \$order; \$repeat++) { //angle rotated through \$a = (2*M_PI / \$order) * \$repeat; \$c = exactify(cos(\$a)); \$s = exactify(sin(\$a)); foreach(\$axes as \$axis) { //make it a unit vector u \$u[0] = \$axis[0]/sqrt(pow(\$axis[0],2)+pow(\$axis[1],2)+pow(\$axis[2],2)); \$u[1] = \$axis[1]/sqrt(pow(\$axis[0],2)+pow(\$axis[1],2)+pow(\$axis[2],2)); \$u[2] = \$axis[2]/sqrt(pow(\$axis[0],2)+pow(\$axis[1],2)+pow(\$axis[2],2)); \$operations[\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]] = array (pow(\$u[0],2)*(1-\$c) + \$c, \$u[0]*\$u[1]*(1-\$c) - \$u[2]*\$s, \$u[0]*\$u[2]*(1-\$c) + \$u[1]*\$s, \$u[0]*\$u[1]*(1-\$c) + \$u[2]*\$s, pow(\$u[1],2)*(1-\$c) + \$c, \$u[1]*\$u[2]*(1-\$c) - \$u[0]*\$s, \$u[0]*\$u[2]*(1-\$c) - \$u[1]*\$s, \$u[1]*\$u[2]*(1-\$c) + \$u[0]*\$s, pow(\$u[2],2)*(1-\$c) + \$c ); for(\$i = 0; \$i < 9; \$i++) { \$operations[\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]][\$i] = exactify(\$operations[\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]][\$i]); } \$operations[\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]]['html'] = \$order.(\$repeat > 1 ? ''.\$repeat.'[' : '[').(\$axis[0] >= 0 ? \$axis[0] : ''.abs(\$axis[0]).'').(\$axis[1] >= 0 ? \$axis[1] : ''.abs(\$axis[1]).'').(\$axis[2] >= 0 ? \$axis[2] : ''.abs(\$axis[2]).'').']'; \$operations[\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]]['type'] = 'C'.\$order; } } } //rotoinversion //OK, so S isn't technically rotoinversion, it's rotoreflection...but it's equivalent \$type['S3'] = 'rotoinversion (order 3)'; \$type['S4'] = 'rotoinversion (order 4)'; \$orders = array(3,4); foreach(\$orders as \$order) { //generate the initial ones by rotating then inverting foreach(\$axes as \$axis) { \$operations['-'.\$order.'1'.\$axis[0].\$axis[1].\$axis[2]] = multiply_matrices(\$operations[\$order.'1'.\$axis[0].\$axis[1].\$axis[2]],\$operations['-1']); \$operations['-'.\$order.'1'.\$axis[0].\$axis[1].\$axis[2]]['html'] = ''.\$order.''.'['.(\$axis[0] >= 0 ? \$axis[0] : ''.abs(\$axis[0]).'').(\$axis[1] >= 0 ? \$axis[1] : ''.abs(\$axis[1]).'').(\$axis[2] >= 0 ? \$axis[2] : ''.abs(\$axis[2]).'').']'; \$operations['-'.\$order.'1'.\$axis[0].\$axis[1].\$axis[2]]['type'] = 'S'.\$order; //generate the rest by repetition for(\$repeat = 2; \$repeat < \$order; \$repeat++) { \$operations['-'.\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]] = multiply_matrices(\$operations['-'.\$order.'1'.\$axis[0].\$axis[1].\$axis[2]],\$operations['-'.\$order.(\$repeat-1).\$axis[0].\$axis[1].\$axis[2]]); \$operations['-'.\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]]['html'] = ''.\$order.''.(\$repeat > 1 ? ''.\$repeat.'[' : '[').(\$axis[0] >= 0 ? \$axis[0] : ''.abs(\$axis[0]).'').(\$axis[1] >= 0 ? \$axis[1] : ''.abs(\$axis[1]).'').(\$axis[2] >= 0 ? \$axis[2] : ''.abs(\$axis[2]).'').']'; \$operations['-'.\$order.\$repeat.\$axis[0].\$axis[1].\$axis[2]]['type'] = 'S'.\$order; } } } //to display all the element matrices generated as a load of tables, uncomment this code /* foreach (\$operations as \$operation) { print '

'.\$operation['html'].' = '. " ".''. " ".'
 '.\$operation[0].' '.\$operation[1].' '.\$operation[2].' '.\$operation[3].' '.\$operation[4].' '.\$operation[5].' '.\$operation[6].' '.\$operation[7].' '.\$operation[8].'

'; }*/ ?>

Welcome to SymGen! This script generates multiplication tables for symmetry elements to test whether they form a complete group. Simply select the symmetry elements in your point group from those available below and then click “generate symmetry table”, or simply pick a point group which has already had its symmetry elements evaluated!

## Custom group

\$longhand) {?>
\$operation) { if(\$operation['type'] == \$shorthand) {?>
symmetry elements string
'.\$operations[\$results[\$first][\$second]]['html'].''; } else { print ''; } } else { print ''; } } ?>

'.\$operations[\$results[\$first][\$second]]['html'].'
• This group contains elements.
• This is an incomplete group. There are xs, where a member operated on a member creates an element not in the group.
• This group is complete.
• This group is abelian.
• This group is non-abelian. Operations which do not commute are highlighted.