diff --git a/hexrd/constants.py b/hexrd/constants.py index 42cf1f0b..932814ae 100644 --- a/hexrd/constants.py +++ b/hexrd/constants.py @@ -82,7 +82,8 @@ zeros_3x1 = np.zeros((3, 1)) zeros_6x1 = np.zeros((6, 1)) -# reference beam direction and eta=0 ref in LAB FRAME for standard geometry +'''reference beam direction and +eta=0 ref in LAB FRAME for standard geometry''' beam_vec = -lab_z eta_vec = lab_x @@ -162,7 +163,9 @@ 3628800.]).astype(np.complex128) """ ->> @AUTHOR: Saransh Singh, Lawrence Livermore National Lab, saransh1@llnl.gov +>> @AUTHOR: Saransh Singh, + Lawrence Livermore National Lab, + saransh1@llnl.gov >> @DATE: 11/28/2022 SS 1.0 original >> @DETAILS: constants for rodrigues FZ """ @@ -177,7 +180,9 @@ ) ''' ->> @AUTHOR: Saransh Singh, Lawrence Livermore National Lab, saransh1@llnl.gov +>> @AUTHOR: Saransh Singh, + Lawrence Livermore National Lab, + saransh1@llnl.gov >> @DATE: 10/28/2020 SS 1.0 original >> @DETAILS: constants for sphere sectors used for IPF coloring ''' @@ -263,7 +268,8 @@ def set_numba_cache(): 4. The NUMBA_CACHE_DIR environment variable is not defined If all of these are true, then numba will try to write to a - directory where it doesn't have permission, and cause the application to + directory where it doesn't have permission, + and cause the application to freeze. Avoid that by setting the cache dir ourselves. """ @@ -316,8 +322,10 @@ def is_writable_file(path): cRestmass = 9.1093837090E-31 ''' -adding another parametrization of the scattering factors. these are more recent -and more accurate. also used in Vesta (copied from there). see: +adding another parametrization of the +scattering factors. these are more recent +and more accurate. also used in Vesta +(copied from there). see: New Analytical coherent Scattering-Factor Functions for Free Atoms and Ions BY D. WAASMAIER AND A. KIRFEL @@ -638,7 +646,9 @@ def is_writable_file(path): 'Cf': ['0'] } ''' -this dictionary tabulates the small nuclear Thomson term fNT for all elements up to Z=92 +this dictionary tabulates the small +nuclear Thomson term fNT for all +elements up to Z=92 ''' fNT = { 'H':-0.00054423,'He':-0.00054817,'Li':-0.00071131,'Be':-0.00097394,'B':-0.0012687,'C':-0.0016442,'N':-0.0019191,'O':-0.0021944, @@ -737,8 +747,10 @@ def is_writable_file(path): 229 ]) -''' this variable encodes all the generators (including translations) for all 230 space groups - will be used to compute the full space group symmetry operators +''' this variable encodes all the generators +(including translations) for all 230 space groups +will be used to compute the full space group symmetry +operators ''' SYM_GL = [ "000 ", "100 ", "01cOOO0 ", @@ -996,8 +1008,10 @@ def is_writable_file(path): } ''' -this dictionary contains the generators encoded in each letter of the generator string -the full symmetry is generated by the repeated action of the generator matrix +this dictionary contains the generators encoded +in each letter of the generator string +the full symmetry is generated by the repeated +action of the generator matrix ''' ''' rotational, inversions, mirrors etc. components @@ -1100,49 +1114,21 @@ def is_writable_file(path): SYM_GENERATORS['Y'] = -1./4. SYM_GENERATORS['Z'] = -1./8. -''' this dictionary contains the space group numbers -which have two origin choices the two values are the -site symmetries of the origin. There are 24 such space -groups -''' -two_origin_choice = { -48 : ['222', '-1'], -50 : ['222/n', '-1'], -59 : ['mm2/n', '-1'], -68 : ['222', '-1'], -70 : ['222', '-1'], -85 : ['-4', '-1'], -86 : ['-4', '-1'], -88 : ['-4', '-1'], -125: ['422', '2/m'], -126: ['422/n', '-1'], -129: ['-4m2', '2/m'], -130: ['-4/ncn', '-1'], -133: ['-4121/c', '-1'], -134: ['-42m', '2/m'], -137: ['-4m2/n', '-1'], -138: ['-4cg', '2/m'], -141: ['-4m2', '2/m'], -142: ['-4c21', '-1'], -201: ['23', '-3'], -203: ['23', '-3'], -222: ['432', '-3'], -224: ['-43m', '-3m'], -227: ['-43m', '-3m'], -228: ['23', '-3'], -} - - ''' - @AUTHOR Saransh Singh, Lawrence Livermore National Lab, saransh1@llnl.gov + @AUTHOR Saransh Singh, + Lawrence Livermore National Lab, + saransh1@llnl.gov @DATE 11/23/2020 SS 1.0 original - @DETAIL. this list of symbols will help us to genrate the point group symmetries - in the cartesian space for any point group. this is needed for the - supergroup symmetry usd in the coloring scheme used in the package. this - needs to be a separate set of routines because the supergroup can be a - point group which is not the laue group of the crystal (e.g. m-3 --> m-3m) - the notation used will be the same as the one used for the space group - without any translations. + @DETAIL. this list of symbols will help us to genrate + the point group symmetries in the cartesian + space for any point group. this is needed for + the supergroup symmetry usd in the coloring + scheme used in the package. this needs to be a + separate set of routines because the supergroup + can be a point group which is not the laue group + of the crystal (e.g. m-3 --> m-3m) the notation + used will be the same as the one used for the + space group without any translations. ''' SYM_GL_PG = { 'c1': '1a', # only identity rotation diff --git a/hexrd/material/material.py b/hexrd/material/material.py index 5ca1ca67..b447c6fd 100644 --- a/hexrd/material/material.py +++ b/hexrd/material/material.py @@ -36,11 +36,11 @@ from hexrd.material.crystallography import PlaneData as PData from hexrd.material import symmetry, unitcell +from hexrd.material.symbols import two_origin_choice from hexrd.valunits import valWUnit from hexrd.constants import (ptable, - ptableinverse, - chargestate, - two_origin_choice) + ptableinverse, + chargestate) from os import path from pathlib import Path @@ -79,6 +79,7 @@ def _kev(x): def _key(x): return x.name + def get_default_sgsetting(sgnum): if sgnum in two_origin_choice: return 1 @@ -187,8 +188,8 @@ def __init__( elif isinstance(material_file, h5py.Group) or form in h5_suffixes: self._readHDFxtal(fhdf=material_file, xtal=name) if sgsetting is not None: - if sgsetting in [0, 1]: - self._sgsetting = sgsetting + if sgsetting in [0, 1]: + self._sgsetting = sgsetting else: # default name self._name = Material.DFLT_XTAL @@ -1436,7 +1437,7 @@ def loadMaterialList(cfgFile): def load_materials_hdf5( - f, dmin=None, kev=None): + f, dmin=None, kev=None): """Load materials from an HDF5 file The file uses the HDF5 file format. diff --git a/hexrd/material/mksupport.py b/hexrd/material/mksupport.py index 08327262..73f71870 100644 --- a/hexrd/material/mksupport.py +++ b/hexrd/material/mksupport.py @@ -1,6 +1,9 @@ -from hexrd.material.symbols import pstr_Elements, sitesym, \ - tworig, PrintPossibleSG, TRIG, pstr_spacegroup,\ - pstr_mkxtal +from hexrd.material.symbols import (pstr_Elements, + two_origin_choice, + PrintPossibleSG, + TRIG, + pstr_spacegroup, + pstr_mkxtal) import h5py import os import numpy as np @@ -8,6 +11,7 @@ import getpass from hexrd.material.unitcell import _StiffnessDict, _pgDict + def mk(filename, xtalname): # print some initial information for the user @@ -23,7 +27,7 @@ def mk(filename, xtalname): AtomInfo = GetAtomInfo() AtomInfo.update({'file': filename, 'xtalname': xtalname, - 'xtal_sys': xtal_sys, 'SG': space_group,\ + 'xtal_sys': xtal_sys, 'SG': space_group, 'SGsetting': iset}) Write2H5File(AtomInfo, lat_param) @@ -275,14 +279,15 @@ def GetSpaceGroup(xtal_sys, btrigonal, bhexset): def SpaceGroupSetting(sgnum): iset = 1 - if(sgnum in tworig): - idx = tworig.index(sgnum) + if(sgnum in two_origin_choice): + sitesym1 = two_origin_choice[sgnum][0] + sitesym2 = two_origin_choice[sgnum][1] print(' ---------------------------------------------') print(' This space group has two origin settings.') print(' The first setting has site symmetry : ' + - sitesym[2*idx - 2]) + sitesym1) print(' the second setting has site symmetry : ' + - sitesym[2*idx - 1]) + sitesym2) iset = input(' Which setting do you wish to use (1/2) : ') if(not iset.isdigit()): raise ValueError("Invalid integer value for atomic number.") @@ -294,7 +299,6 @@ def SpaceGroupSetting(sgnum): return iset-1 - def GetAtomInfo(): print(pstr_Elements) diff --git a/hexrd/material/symbols.py b/hexrd/material/symbols.py index ccc65ef3..18d8479b 100644 --- a/hexrd/material/symbols.py +++ b/hexrd/material/symbols.py @@ -120,17 +120,37 @@ '89:Ac 90:Th 91:Pa 92:U' + "\n" \ ' ----------------------------------------------------------------------------------------------------------' -sitesym = ['222 ',' -1 ','222/n ',' -1 ','mm2/n ',' -1 ', \ -'222 ',' -1 ','222 ',' -1 ','-4 ',' -1 ', \ -'-4 ',' -1 ','-4 ',' -1 ','422 ','2/m ', \ -'422/n ',' -1 ','-4m2 ','2/m ','-4/ncn ',' -1 ', \ -'-4121/c',' -1 ','-42m ','2/m ','-4m2/n ',' -1 ', \ -'-4cg ','2/m ','-4m2 ','2/m ','-4c21 ',' -1 ', \ -'23 ',' -3 ','23 ',' -3 ','432 ',' -3 ', \ -'-43m ','-3m ','-43m ','-3m ','23 ',' -3 '] - -tworig = [48,50,59,68,70,85,86,88,125,126,129,130,133,134,137,138,\ -141,142,201,203,222,224,227,228] +''' this dictionary contains the space group numbers +which have two origin choices the two values are the +site symmetries of the origin. There are 24 such space +groups +''' +two_origin_choice = { +48 : ['222', '-1'], +50 : ['222/n', '-1'], +59 : ['mm2/n', '-1'], +68 : ['222', '-1'], +70 : ['222', '-1'], +85 : ['-4', '-1'], +86 : ['-4', '-1'], +88 : ['-4', '-1'], +125: ['422', '2/m'], +126: ['422/n', '-1'], +129: ['-4m2', '2/m'], +130: ['-4/ncn', '-1'], +133: ['-4121/c', '-1'], +134: ['-42m', '2/m'], +137: ['-4m2/n', '-1'], +138: ['-4cg', '2/m'], +141: ['-4m2', '2/m'], +142: ['-4c21', '-1'], +201: ['23', '-3'], +203: ['23', '-3'], +222: ['432', '-3'], +224: ['-43m', '-3m'], +227: ['-43m', '-3m'], +228: ['23', '-3'], +} def PrintPossibleSG(xtal_sys): diff --git a/hexrd/material/symmetry.py b/hexrd/material/symmetry.py index 5ea30a1b..0d614f7f 100644 --- a/hexrd/material/symmetry.py +++ b/hexrd/material/symmetry.py @@ -31,9 +31,9 @@ import numpy as np from numba import njit -from numpy import array, sqrt, pi, \ - vstack, c_, dot, \ - argmax +from numpy import (array, sqrt, pi, + vstack, c_, dot, + argmax) # from hexrd.rotations import quatOfAngleAxis, quatProductMatrix, fixQuat from hexrd import rotations as rot @@ -41,8 +41,9 @@ from hexrd.utils.decorators import memoize # Imports in case others are importing from here -from hexrd.rotations import toFundamentalRegion, ltypeOfLaueGroup, \ - quatOfLaueGroup +from hexrd.rotations import (toFundamentalRegion, + ltypeOfLaueGroup, + quatOfLaueGroup) # ============================================================================= @@ -78,8 +79,8 @@ def GeneratorString(sgnum): return constants.SYM_GL[sg] -def MakeGenerators(genstr, setting): +def MakeGenerators(genstr, setting): t = 'aOOO' mat = SYM_fillgen(t) @@ -99,7 +100,7 @@ def MakeGenerators(genstr, setting): if(n > 0): for i in range(n): istart = 2 + i * 4 - istop = 2 + (i+1) * 4 + istop = 2 + (i+1) * 4 t = genstr[istart:istop] @@ -114,39 +115,39 @@ def MakeGenerators(genstr, setting): if(genstr[istop] != '0'): if(setting != 0): t = genstr[istop+1:istop+4] - t = 'a' + t # get the translation without any rotation - sym = np.squeeze(SYM_fillgen(t, sgn=-1)) + t = 'a' + t # get the translation without any rotation + sym = np.squeeze(SYM_fillgen(t, sgn=-1)) sym2 = np.squeeze(SYM_fillgen(t)) for i in range(1, genmat.shape[0]): generator = np.dot(sym2, np.dot( - np.squeeze(genmat[i,:,:]), - sym)) - frac = np.modf(generator[0:3,3])[0] + np.squeeze(genmat[i, :, :]), + sym)) + frac = np.modf(generator[0:3, 3])[0] frac[frac < 0.] += 1. frac[np.abs(frac) < 1E-5] = 0.0 frac[np.abs(frac-1.0) < 1E-5] = 0.0 - generator[0:3,3] = frac - genmat[i,:,:] = generator + generator[0:3, 3] = frac + genmat[i, :, :] = generator return genmat, centrosymmetric + def SYM_fillgen(t, sgn=1): - mat = np.zeros([4,4]) - mat[3,3] = 1. + mat = np.zeros([4, 4]) + mat[3, 3] = 1. - mat[0:3,0:3] = constants.SYM_GENERATORS[t[0]] - mat[0:3,3] = sgn*np.array([constants.SYM_GENERATORS[t[1]], - constants.SYM_GENERATORS[t[2]], - constants.SYM_GENERATORS[t[3]] - ]) + mat[0:3, 0:3] = constants.SYM_GENERATORS[t[0]] + mat[0:3, 3] = sgn*np.array([constants.SYM_GENERATORS[t[1]], + constants.SYM_GENERATORS[t[2]], + constants.SYM_GENERATORS[t[3]] + ]) - mat = np.broadcast_to(mat, [1,4,4]) + mat = np.broadcast_to(mat, [1, 4, 4]) return mat @memoize(maxsize=20) def GenerateSGSym(sgnum, setting=0): - ''' get the generators for a space group using the generator string @@ -173,22 +174,22 @@ def GenerateSGSym(sgnum, setting=0): k1 = 0 while k1 < nsym: - g1 = np.squeeze(SYM_SG[k1,:,:]) + g1 = np.squeeze(SYM_SG[k1, :, :]) k2 = k1 while k2 < nsym: - g2 = np.squeeze(SYM_SG[k2,:,:]) + g2 = np.squeeze(SYM_SG[k2, :, :]) gnew = np.dot(g1, g2) # only fractional parts - frac = np.modf(gnew[0:3,3])[0] + frac = np.modf(gnew[0:3, 3])[0] frac[frac < 0.] += 1. frac[np.abs(frac) < 1E-5] = 0.0 frac[np.abs(frac-1.0) < 1E-5] = 0.0 - gnew[0:3,3] = frac + gnew[0:3, 3] = frac if(isnew(gnew, SYM_SG)): - gnew = np.broadcast_to(gnew, [1,4,4]) + gnew = np.broadcast_to(gnew, [1, 4, 4]) SYM_SG = np.concatenate((SYM_SG, gnew)) nsym += 1 @@ -203,12 +204,12 @@ def GenerateSGSym(sgnum, setting=0): SYM_PG_d_laue = GeneratePGSym_Laue(SYM_PG_d) for s in SYM_PG_d: - if(np.allclose(-np.eye(3),s)): + if(np.allclose(-np.eye(3), s)): centrosymmetric = True - return SYM_SG, SYM_PG_d, SYM_PG_d_laue, centrosymmetric, symmorphic + def GeneratePGSym(SYM_SG): ''' calculate the direct space point group symmetries @@ -222,19 +223,20 @@ def GeneratePGSym(SYM_SG): nsgsym = SYM_SG.shape[0] # first fill the identity rotation - SYM_PG_d = SYM_SG[0,0:3,0:3] - SYM_PG_d = np.broadcast_to(SYM_PG_d,[1,3,3]) - - for i in range(1,nsgsym): - g = SYM_SG[i,:,:] - t = g[0:3,3] - g = g[0:3,0:3] - if(isnew(g,SYM_PG_d)): - g = np.broadcast_to(g,[1,3,3]) + SYM_PG_d = SYM_SG[0, 0:3, 0:3] + SYM_PG_d = np.broadcast_to(SYM_PG_d, [1, 3, 3]) + + for i in range(1, nsgsym): + g = SYM_SG[i, :, :] + t = g[0:3, 3] + g = g[0:3, 0:3] + if(isnew(g, SYM_PG_d)): + g = np.broadcast_to(g, [1, 3, 3]) SYM_PG_d = np.concatenate((SYM_PG_d, g)) return SYM_PG_d.astype(np.int32) + def GeneratePGSym_Laue(SYM_PG_d): ''' generate the laue group symmetry for the given set of @@ -248,7 +250,7 @@ def GeneratePGSym_Laue(SYM_PG_d): first check if the group already has the inversion symmetry ''' for s in SYM_PG_d: - if(np.allclose(s,-np.eye(3))): + if(np.allclose(s, -np.eye(3))): return SYM_PG_d ''' @@ -256,7 +258,7 @@ def GeneratePGSym_Laue(SYM_PG_d): add the inversion symmetry ''' SYM_PG_d_laue = SYM_PG_d - g = np.broadcast_to(-np.eye(3).astype(np.int32),[1,3,3]) + g = np.broadcast_to(-np.eye(3).astype(np.int32), [1, 3, 3]) SYM_PG_d_laue = np.concatenate((SYM_PG_d_laue, g)) ''' @@ -266,14 +268,14 @@ def GeneratePGSym_Laue(SYM_PG_d): nsym = SYM_PG_d_laue.shape[0] k1 = 0 while k1 < nsym: - g1 = np.squeeze(SYM_PG_d_laue[k1,:,:]) + g1 = np.squeeze(SYM_PG_d_laue[k1, :, :]) k2 = k1 while k2 < nsym: - g2 = np.squeeze(SYM_PG_d_laue[k2,:,:]) + g2 = np.squeeze(SYM_PG_d_laue[k2, :, :]) gnew = np.dot(g1, g2) if(isnew(gnew, SYM_PG_d_laue)): - gnew = np.broadcast_to(gnew, [1,3,3]) + gnew = np.broadcast_to(gnew, [1, 3, 3]) SYM_PG_d_laue = np.concatenate((SYM_PG_d_laue, gnew)) nsym += 1 @@ -295,6 +297,7 @@ def isnew(mat, sym_mats): return False return True + def latticeType(sgnum): if(sgnum <= 2): @@ -309,7 +312,7 @@ def latticeType(sgnum): return 'trigonal' elif(sgnum > 167 and sgnum <= 194): return 'hexagonal' - elif(sgnum > 194 and sgnum <=230): + elif(sgnum > 194 and sgnum <= 230): return 'cubic' else: raise RuntimeError('symmetry.latticeType: unknown space group number') @@ -323,14 +326,15 @@ def MakeGenerators_PGSYM(pggenstr): for any point group. this is needed for the coloring routines ''' ngen = int(pggenstr[0]) - SYM_GEN_PG = np.zeros([ngen,3,3]) + SYM_GEN_PG = np.zeros([ngen, 3, 3]) for i in range(ngen): s = pggenstr[i+1] - SYM_GEN_PG[i,:,:] = constants.SYM_GENERATORS[s] + SYM_GEN_PG[i, :, :] = constants.SYM_GENERATORS[s] return SYM_GEN_PG + def GeneratePGSYM(pgsym): ''' @AUTHOR Saransh Singh, Lawrence Livermore National Lab, saransh1@llnl.gov @@ -345,7 +349,6 @@ def GeneratePGSYM(pgsym): generate the powers of the group ''' - ''' now go through the group actions and see if its a new matrix if it is then add it to the group @@ -353,14 +356,14 @@ def GeneratePGSYM(pgsym): nsym = SYM_GEN_PG.shape[0] k1 = 0 while k1 < nsym: - g1 = np.squeeze(SYM_GEN_PG[k1,:,:]) + g1 = np.squeeze(SYM_GEN_PG[k1, :, :]) k2 = k1 while k2 < nsym: - g2 = np.squeeze(SYM_GEN_PG[k2,:,:]) + g2 = np.squeeze(SYM_GEN_PG[k2, :, :]) gnew = np.dot(g1, g2) if(isnew(gnew, SYM_GEN_PG)): - gnew = np.broadcast_to(gnew, [1,3,3]) + gnew = np.broadcast_to(gnew, [1, 3, 3]) SYM_GEN_PG = np.concatenate((SYM_GEN_PG, gnew)) nsym += 1