#!/usr/bin/sage import sys import numpy as np from sage.all import * def get_VSpU( M ): N = copy(M) for i in range(N.nrows()): N[i,i%3] -= 1 S,U,V = N.smith_form() Sp = Matrix( QQ, S.transpose() ) for i in range(3): if not Sp[i,i]==0: Sp[i,i] = 1.0 / Sp[i,i] return V*Sp*U def get_VSpU_sets(g1s, g2s): VSpU_sets = [] generator_sets = [] for g3 in ( False, True ): # for inversion for g1 in g1s: for g2 in g2s: if g2 is not False: if np.equal(g1, g2).all(): continue if np.equal(g1, np.dot(inv, g2)).all(): continue genes = [g1, g2] else: genes = [g1,] if g3: genes_new = [] for g in genes: if np.linalg.det(g) < 0: genes_new.append(np.dot(inv, g)) else: genes_new.append(g) genes_new.append(inv) if np.linalg.det(g1) < 0: is_found = False for g1_comp in g1s: if np.equal(genes_new[0], g1_comp).all(): is_found = True break if is_found: continue if g2 is not False: if np.linalg.det(g2) < 0: is_found = False for g2_comp in g2s: if np.equal(genes_new[1], g2_comp).all(): is_found = True break if is_found: continue else: genes_new = genes M = Matrix(3, 3, genes_new[0]) if len(genes_new) > 1: for g in genes_new[1:]: M = M.stack(Matrix(3, 3, g)) VSpU_sets.append(get_VSpU(M)) generator_sets.append( M ) return VSpU_sets, generator_sets def get_rotation_primitive( g1s, g2s, T ): if T is not None: g1s_new = [] g2s_new = [] g1s_old = [] g2s_old = [] for g in g1s: # print g, "-->" try: M = Matrix(ZZ,T*Matrix(QQ, g)*T.inverse()) # print M g1s_new.append(np.array(M)) g1s_old.append(g) except TypeError: print "Not integer matrix, pass this matrix" for g in g2s: if g: # print g, "-->" try: M = Matrix(ZZ, T*Matrix(QQ, g)*T.inverse()) # print M g2s_new.append(np.array(M)) g2s_old.append(g) except TypeError: print "Not integer matrix, pass this matrix" else: g2s_new.append(False) g2s_old.append(False) return g1s_new, g2s_new, g1s_old, g2s_old def write_generators(generator_sets): print "{" for count, M in enumerate( generator_sets ): print " { /* %d */" % (count+1) for i in range( 3 ): print " { ", for j in range( 3 ): for k in range( 3 ): if M.nrows() // 3 > i: print "%d," % M[i*3+j,k], else: print " 0,", print "}," print " }," print "};" def write_VSpU(VSpU_sets): print "{" for count, VSpU in enumerate( VSpU_sets ): print " { /* %d */" % (count+1) for colvals in VSpU: print " {", for i in range( 9 ): if i < len( colvals ): num = colvals[i].numerator() den = colvals[i].denominator() if den == 1: print "%d," % ( num ), else: print "%d.0/%d," % ( num, den ), else: print " 0,", print "}," print " }," print "};" identity = [[ 1, 0, 0], [ 0, 1, 0], [ 0, 0, 1]] inv = [[-1, 0, 0], [ 0,-1, 0], [ 0, 0,-1]] # Tetragonal rot4z = [[ 0,-1, 0], [ 1, 0, 0], [ 0, 0, 1]] rot4zi = [[ 0, 1, 0], [-1, 0, 0], [ 0, 0,-1]] rot2z = [[-1, 0, 0], [ 0,-1, 0], [ 0, 0, 1]] rot2zi = [[ 1, 0, 0], [ 0, 1, 0], [ 0, 0,-1]] rot2x = [[ 1, 0, 0], [ 0,-1, 0], [ 0, 0,-1]] rot2xi = [[-1, 0, 0], [ 0, 1, 0], [ 0, 0, 1]] rot3xyz = [[ 0, 0, 1], [ 1, 0, 0], [ 0, 1, 0]] rot3xyzi = [[ 0, 0,-1], [-1, 0, 0], [ 0,-1, 0]] hexa2_ab = [[ 0,-1, 0], [-1, 0, 0], [ 0, 0,-1]] hexa2_abi = [[ 0, 1, 0], [ 1, 0, 0], [ 0, 0, 1]] rot6z = [[ 1,-1, 0], [ 1, 0, 0], [ 0, 0, 1]] rot6zi = [[-1, 1, 0], [-1, 0, 0], [ 0, 0,-1]] trigo2ab = [[ 0, 1, 0], [ 1, 0, 0], [ 0, 0,-1]] trigo2abi = [[ 0,-1, 0], [-1, 0, 0], [ 0, 0, 1]] rot3z = [[ 0,-1, 0], [ 1,-1, 0], [ 0, 0, 1]] rot3zi = [[ 0, 1, 0], [-1, 1, 0], [ 0, 0,-1]] rot2y = [[-1, 0, 0], [ 0, 1, 0], [ 0, 0,-1]] rot2yi = [[ 1, 0, 0], [ 0,-1, 0], [ 0, 0, 1]] BCC = Matrix(QQ, [[ 0, 1, 1], [ 1, 0, 1], [ 1, 1, 0]]) FCC = Matrix(QQ, [[-1, 1, 1], [ 1,-1, 1], [ 1, 1,-1]]) CC = Matrix(QQ, [[ 1,-1, 0], [ 1, 1, 0], [ 0, 0, 1]]) BC = Matrix(QQ, [[ 1, 0, 1], [ 0, 1, 0], [-1, 0, 1]]) AC = Matrix(QQ, [[ 1, 0, 0], [ 0, 1, 1], [ 0,-1, 1]]) RC = Matrix(QQ, [[ 1, 0, 1], [-1, 1, 1], [ 0,-1, 1]]) # Parse options from optparse import OptionParser parser = OptionParser() parser.set_defaults(is_tricli=False, is_monocli=False, is_ortho=False, is_tetra=False, is_rhombo=False, is_trigo=False, is_hexa=False, is_cubic=False, is_bcc=False, is_fcc=False, is_ac=False, is_bc=False, is_cc=False, is_rc=False) parser.add_option("--tricli", dest="is_tricli", action="store_true") parser.add_option("--monocli", dest="is_monocli", action="store_true") parser.add_option("--ortho", dest="is_ortho", action="store_true") parser.add_option("--tetra", dest="is_tetra", action="store_true") parser.add_option("--rhombo", dest="is_rhombo", action="store_true") parser.add_option("--trigo", dest="is_trigo", action="store_true") parser.add_option("--hexa", dest="is_hexa", action="store_true") parser.add_option("--cubic", dest="is_cubic", action="store_true") parser.add_option("--bcc", dest="is_bcc", action="store_true") parser.add_option("--fcc", dest="is_fcc", action="store_true") parser.add_option("--ac", dest="is_ac", action="store_true") parser.add_option("--bc", dest="is_bc", action="store_true") parser.add_option("--cc", dest="is_cc", action="store_true") parser.add_option("--rc", dest="is_rc", action="store_true") parser.add_option("-g", dest="is_generator", action="store_true") (options, args) = parser.parse_args() g1s = None g2s = None g1s_old = None g2s_old = None if options.is_tricli: g1s = ( identity, ) g2s = ( False, ) if options.is_monocli: g1s = ( rot2x, rot2y, rot2z, rot2xi, rot2yi, rot2zi ) g2s = ( False, ) if options.is_bcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BCC ) if options.is_ac: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, AC ) if options.is_bc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BC ) if options.is_cc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, CC ) if options.is_ortho: g1s = ( rot2z, rot2zi ) g2s = ( rot2x, rot2xi ) if options.is_bcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BCC ) if options.is_fcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, FCC ) if options.is_ac: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, AC ) if options.is_bc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BC ) if options.is_cc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, CC ) if options.is_tetra: g1s = ( rot4z, rot4zi ) g2s = ( False, rot2x, rot2xi ) if options.is_bcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BCC ) # if options.is_rhombo: # g1s = ( rot3xyz, rot3xyzi ) # g2s = ( False, hexa2_ab, trigo2ab ) if options.is_trigo: g1s = ( rot3z, rot3zi ) g2s = ( False, hexa2_ab, trigo2ab, hexa2_abi, trigo2abi ) if options.is_rc: # hP g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, RC ) if options.is_rhombo: # hR g1s = ( rot3z, rot3zi ) g2s = ( False, hexa2_ab, trigo2ab, hexa2_abi, trigo2abi ) g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, RC ) g1s_old = None g2s_old = None if options.is_hexa: g1s = ( rot6z, rot6zi ) g2s = ( False, hexa2_ab, hexa2_abi ) if options.is_cubic: g1s = ( rot4z, rot2z, rot4zi, rot2zi ) g2s = ( rot3xyz, rot3xyzi ) if options.is_bcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, BCC ) if options.is_fcc: g1s, g2s, g1s_old, g2s_old = get_rotation_primitive( g1s, g2s, FCC ) if g1s is None: print "Option is needed. See \'make_VSpU.py -h\'" else: if g1s_old is None: VSpU_sets, generator_sets = get_VSpU_sets( g1s, g2s ) else: VSpU_sets = get_VSpU_sets( g1s, g2s )[0] generator_sets = get_VSpU_sets( g1s_old, g2s_old )[1] centering = "" if options.is_fcc: centering = "_F" if options.is_bcc: centering = "_I" if options.is_ac: centering = "_A" if options.is_bc: centering = "_B" if options.is_cc: centering = "_C" if options.is_generator: if options.is_tricli: print "static int tricli_generators[][3][9] =" if options.is_monocli: print "static int monocli_generators[][3][9] =" if options.is_ortho: print "static int ortho_generators[][3][9] =" if options.is_tetra: print "static int tetra_generators[][3][9] =" if options.is_trigo: if options.is_rc: print "static int rhombo_h_generators[][3][9] =" else: print "static int trigo_generators[][3][9] =" if options.is_rhombo: print "static int rhombo_p_generators[][3][9] =" if options.is_hexa: print "static int hexa_generators[][3][9] =" if options.is_cubic: print "static int cubic_generators[][3][9] =" write_generators(generator_sets) print else: if options.is_tricli: print "static double tricli_VSpU[][3][9] =" if options.is_monocli: print "static double monocli%s_VSpU[][3][9] =" % centering if options.is_ortho: print "static double ortho%s_VSpU[][3][9] =" % centering if options.is_tetra: print "static double tetra%s_VSpU[][3][9] =" % centering if options.is_trigo: if options.is_rc: print "static double rhombo_h_VSpU[][3][9] =" else: print "static double trigo_VSpU[][3][9] =" if options.is_rhombo: print "static double rhombo_p_VSpU[][3][9] =" if options.is_hexa: print "static double hexa_VSpU[][3][9] =" if options.is_cubic: print "static double cubic%s_VSpU[][3][9] =" write_VSpU(VSpU_sets) print