Changeset 5364
- Timestamp:
- Nov 5, 2022 10:07:32 PM (4 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nistlat.py
r5360 r5364 33 33 import re 34 34 import numpy as np 35 import GSASIIlattice as G2lat 35 36 36 37 nistlattice = "/Users/toby/boxGSASII/bin/LATTIC" … … 39 40 centerLbl = {'P':'Primitive', 'A':'A-centered', 'B':'B-centered', 'C':'C-centered', 40 41 'F':'Face-centered', 'I':' Body-centered', 'R':'Rhombohedral', 'H':'Rhombohedral'} 41 42 def showCell(cell,center ,setting):42 43 def showCell(cell,center='P',setting=' ',*ignored): 43 44 '''show unit cell input or output nicely formatted. 44 :param list cell: six lattice constants as float values. 45 :param list cell: six lattice constants as float values; a 7th volume value 46 is ignored if present. 45 47 :param str center: cell centering code; one of P/A/B/C/F/I/R 46 48 Note that 'R' is used for rhombohedral lattices in either … … 50 52 :returns: a formatted string 51 53 ''' 52 s = "{:.4f} {:.4f} {:.4f} {:.3f} {:.3f} {:.3f}".format(*cell )54 s = "{:.4f} {:.4f} {:.4f} {:.3f} {:.3f} {:.3f}".format(*cell[:6]) 53 55 s += ' ' + centerLbl.get(center,'?') 54 56 if setting.strip(): s += '-' + setting 55 57 return s 56 58 59 def printCell(label,*args,**kwargs): 60 print(label,showCell(*args,**kwargs)) 61 57 62 def uniqCells(cellList): 58 '''remove duplicated cells from a cell output list 63 '''remove duplicated cells from a cell output list from :func:`ReduceCell` 59 64 :param list cellList: A list of reduced cells where each entry represents a 60 65 reduced cell as (_,cell,_,_,center,...) where cell has six lattice … … 105 110 3: generate sub- and supercells 106 111 :param int deltaV: volume ratios for sub/supercells if mode != 0 as 107 ratio of original cell to smallest subcell or largest supercell . Ignored108 if mode=0.112 ratio of original cell to smallest subcell or largest supercell 113 to original cell. Ignored if mode=0. Otherwise should be 2, 3, 4 or 5 109 114 :param str output: name of file to write the NIST*LATTICE output 110 115 :returns: a dict with item 'input' with input cell as (cell,center,setting) … … 342 347 return xforms 343 348 349 def CellSymSearch(cellin, center, tolerance=3*[0.2]+3*[1], mode=0, 350 deltaV=2, minsym=' ', output=None): 351 '''Search for a higher symmetry lattice related to an input unit cell, 352 and optionally to the supercells and/or subcells with a specified 353 volume ratio to the input cell. 354 355 :param list cellin: six lattice constants as float values 356 :param str center: cell centering code; one of P/A/B/C/F/I/R 357 Note that 'R' is used for rhombohedral lattices in either 358 hexagonal or rhombohedral (primitive) cells 359 :param list tolerance: comparison tolerances for a, b, c, alpha, beta 360 & gamma (defaults to [0.2,0.2,0.2,1.,1.,1.] 361 :param int mode: 362 0: use only input cell, 363 1: generate supercells, 364 2: generate subcells 365 3: generate sub- and supercells 366 :param int deltaV: volume ratios for sub/supercells if mode != 0 as 367 ratio of original cell to smallest subcell or largest supercell 368 to original cell. Ignored if mode=0. Otherwise should be 2, 3, 4 or 5 369 :param ? minsym: 370 :param str output: name of file to write the NIST*LATTICE output 371 372 :returns: a list of processed cells (only one if mode=0) where for each cell the 373 the following items are included: conventional input cell; reduced input cell; 374 symmetry-generated conventional cell; symmetry-generated reduced cell; 375 matrix to convert sym-generated output cell to input conventional cell 376 ''' 377 # setting is non-blank for rhombohedral lattices (center=R) only. 378 # setting = R for rhob axes 379 # setting = H for hex. axes 380 setting = " " 381 (a,b,c,alpha,beta,gamma) = cellin 382 celldict = {} 383 if center == "R" and alpha == 90 and beta == 90 and gamma == 120: 384 setting = "H" 385 elif center == "R" : 386 setting = "R" 387 # prepare input and start program 388 cellline = '{:10.4f}{:10.4f}{:10.4f}{:10.3f}{:10.3f}{:10.3f}'.format(*cellin) 389 inp = "SYM 1\n" 390 inp += "R{:1d} {:2d} {:10.5f}{:10.5f}{:10.5f}{:10.5f}{:10.5f}{:10.5f}\n".format( 391 mode,deltaV,*tolerance) 392 inp += "{:1d} {:1d}{:1d} {}{}{}\n".format(mode,2,deltaV,center,setting,cellline) 393 p = subprocess.Popen([nistlattice], 394 stdin=subprocess.PIPE, 395 stdout=subprocess.PIPE, 396 stderr=subprocess.PIPE) 397 p.stdin.write(bytearray(inp,'utf8')) 398 p.stdin.close() 399 # read output and parse 400 err = p.stderr.read() 401 402 d = 1 403 lines = [b.decode() for b in p.stdout.readlines()] 404 p.terminate() 405 fp = None 406 if output: fp = open(output,'w') 407 if fp: 408 for line in lines: emulateLP(line,fp) 409 fp.close() 410 lnum = 0 411 d = 1 412 startCellList = [] # reduced cell(s) as (determinant, xform-matrix, reduced-cell, volume) save for internal use 413 symCellList = [] 414 try: 415 # get list of starting cells 416 while lnum < len(lines): 417 line = lines[lnum] 418 lnum += 1 419 pat = r"T 2= (.*)/ (.*)/ (.*)" # transform matrix 420 s = re.split(pat,line) 421 if len(s) > 1: 422 mat = [[float(j) for j in re.split(r" *([\d\.-]*) *",i,maxsplit=3)[1::2]] 423 for i in s[1:-1]] 424 pat = r"Delta =(.*)" # Volume ratio (if mode >0) 425 s = re.split(pat,line) 426 if len(s) > 1: 427 d = float(eval(s[1])) 428 429 pat = r"CELL 2=(.*)V2=(.*)" # cell lattice and volume 430 s = re.split(pat,line) 431 if len(s) > 1: 432 lat = [float(i) for i in re.split(r" *([\d\.-]*) *",s[1],maxsplit=6)[1::2]] 433 vol = float(re.split(r" *([\d\.-]*) *",s[2],maxsplit=1)[1]) 434 startCellList.append((d,mat,lat,vol)) 435 if " ** Symmetry" in line: 436 break 437 #====================================================================== 438 # for each input-generated cell, get sets of generated H-matrices 439 for icell,cellstuff in enumerate(startCellList): 440 while lnum < len(lines): 441 line = lines[lnum] 442 lnum += 1 443 pat = r"CELL 1=(.*)V1=(.*)" # cell lattice and volume 444 s = re.split(pat,line) 445 if len(s) > 1: 446 lat = [float(i) for i in re.split(r" *([\d\.-]*) *",s[1],maxsplit=6)[1::2]] 447 vol = float(re.split(r" *([\d\.-]*) *",s[2],maxsplit=1)[1]) 448 if not np.allclose(cellstuff[2],lat): 449 print('Warning mismatch between list of reduced cells and' 450 ' processed output at line', 451 lnum) 452 print('cell info=',cellstuff) 453 print('lat,vol=',lat,vol) 454 break 455 while lnum < len(lines): 456 line = lines[lnum] 457 lnum += 1 458 if ' H Matrix ' in lines[lnum] and ' Determinant' in lines[lnum]: 459 lnum += 2 460 break 461 # for each H-matrix, compute a new reduced cell 462 xformSum = np.zeros(7) 463 xformCount = 0 464 while lnum < len(lines): 465 line = lines[lnum] 466 sl = lines[lnum].split() 467 if len(sl) == 10: 468 sl = [float(i) for i in sl] 469 m = 3*[3*[0]] # forward matrix 470 im = 3*[3*[0]] # inverse matrix 471 tol = 6*[0] 472 m[0] = sl[0:3] 473 im[0] = sl[3:6] 474 tol[0:3] = sl[6:9] 475 #det = sl[9] 476 477 lnum += 1 478 sl = [float(i) for i in lines[lnum].split()] 479 m[1] = sl[0:3] 480 im[1] = sl[3:6] 481 tol[3:] = sl[6:9] 482 483 lnum += 1 484 sl = [float(i) for i in lines[lnum].split()] 485 m[2] = sl[0:3] 486 im[2] = sl[3:6] 487 xformSum += G2lat.TransformCell(lat,m) 488 xformCount += 1 489 lnum += 1 490 491 # got to end of output for current cell, process this input 492 if 50*'-' in line: 493 if xformCount: 494 inRedCell = (startCellList[icell][2], 'P', ' ') 495 if icell ==0: 496 inCnvCell = (cellin, center, setting) 497 red2convInp = np.linalg.inv(startCellList[0][1]) 498 else: 499 inCnvCell = ConvCell(startCellList[icell][2]) 500 red2convInp = inCnvCell[3] 501 redCell = ([j for j in (xformSum/xformCount)[:6]], 'P', ' ') 502 cnvCell = ConvCell(redCell[0][:6]) 503 # steps to walk back conventional cell back to original 504 #c1 = G2lat.TransformCell(cnvCell[0],np.linalg.inv(cnvCell[3])) 505 #c2 = G2lat.TransformCell(c1[:6],im) # use last, as they are all equiv. 506 #c3 = G2lat.TransformCell(c2[:6],red2convInp) 507 cnv2origMat = np.dot(np.dot(red2convInp,im),np.linalg.inv(cnvCell[3])) 508 #c3 = G2lat.TransformCell(cnvCell[0],cnv2origMat) 509 symCellList.append(( 510 inCnvCell[:3], # input cell (conventional) 511 inRedCell, # input cell (reduced) 512 cnvCell[:3], # symmetry-generated conventional cell 513 redCell, # symmetry-generated reduced cell 514 cnv2origMat, # matrix to convert sym-generated output cell to input conventional cell 515 )) 516 break # go on to next input-generated cell 517 518 519 except Exception as msg: 520 print('Parse error at line ',lnum,'\n',msg) 521 print(line) 522 return celldict 523 finally: 524 p.terminate() 525 if len(symCellList) == 0 or len(err) > 0: 526 print('Error:' ,err.decode()) 527 return symCellList 528 344 529 if __name__ == '__main__': # test code 345 530 346 import GSASIIlattice as G2lat 531 cell = [14.259, 22.539, 8.741, 90., 114.1, 90.] 532 center = 'C' 533 print('CellSymSearch output') 534 for i in CellSymSearch(cell, center, output='/tmp/cellsym.txt'): 535 print('\ninp-conv, inp-red, out-conv, out-red, out(conv)->inp(conv)') 536 for j in i: print(j) 537 538 print('\n\nCellSymSearch output') 539 for i in CellSymSearch(cell, center, output='/tmp/cellsym.txt', mode=3): 540 print('\ninp-conv, inp-red, out-conv, out-red, out(conv)->inp(conv)') 541 for j in i: print(j) 542 543 import sys; sys.exit() 544 347 545 cell1 = (5.03461,5.03461,13.74753,90,90,120) 348 546 center1 = 'R' … … 387 585 cellin = [5.,5.,5.,85.,85.,85.,] 388 586 cellList = ConvCell(cellin) 389 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList [:3]))587 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList)) 390 588 mat = cellList[-1] 391 589 print('test with\n',mat) … … 395 593 cellin = [3.9051,3.9051,7,99.537,99.537,100.389] 396 594 cellList = ConvCell(cellin) 397 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList [:3]))595 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList)) 398 596 mat = cellList[-1] 399 597 print('test with\n',mat) … … 403 601 cellin = [5.,5.,7.,90.,90.,120.,] 404 602 cellList = ConvCell(cellin) 405 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList [:3]))603 print('Input reduced cell',showCell(cellin,'P',' '),'\nout',showCell(*cellList)) 406 604 mat = cellList[-1] 407 605 print('test with\n',mat)
Note: See TracChangeset
for help on using the changeset viewer.