Changeset 5364


Ignore:
Timestamp:
Nov 5, 2022 10:07:32 PM (4 months ago)
Author:
toby
Message:

NIST*LATTICE api done for now; wait until binaries are built for common platforms

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nistlat.py

    r5360 r5364  
    3333import re
    3434import numpy as np
     35import GSASIIlattice as G2lat
    3536
    3637nistlattice = "/Users/toby/boxGSASII/bin/LATTIC"
     
    3940centerLbl = {'P':'Primitive', 'A':'A-centered', 'B':'B-centered', 'C':'C-centered',
    4041        'F':'Face-centered', 'I':' Body-centered', 'R':'Rhombohedral', 'H':'Rhombohedral'}
    41 
    42 def showCell(cell,center,setting):
     42   
     43def showCell(cell,center='P',setting=' ',*ignored):
    4344    '''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.
    4547    :param str center: cell centering code; one of P/A/B/C/F/I/R
    4648      Note that 'R' is used for rhombohedral lattices in either
     
    5052    :returns: a formatted string
    5153    '''
    52     s = "{:.4f} {:.4f} {:.4f} {:.3f} {:.3f} {:.3f}".format(*cell)
     54    s = "{:.4f} {:.4f} {:.4f} {:.3f} {:.3f} {:.3f}".format(*cell[:6])
    5355    s += '  ' + centerLbl.get(center,'?')
    5456    if setting.strip(): s += '-' + setting
    5557    return s
    5658
     59def printCell(label,*args,**kwargs):
     60    print(label,showCell(*args,**kwargs))
     61
    5762def uniqCells(cellList):
    58     '''remove duplicated cells from a cell output list
     63    '''remove duplicated cells from a cell output list from :func:`ReduceCell`
    5964    :param list cellList: A list of reduced cells where each entry represents a
    6065      reduced cell as (_,cell,_,_,center,...) where cell has six lattice
     
    105110        3: generate sub- and supercells
    106111    :param int deltaV: volume ratios for sub/supercells if mode != 0 as
    107       ratio of original cell to smallest subcell or largest supercell. Ignored
    108       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
    109114    :param str output: name of file to write the NIST*LATTICE output 
    110115    :returns: a dict with item 'input' with input cell as (cell,center,setting)
     
    342347    return xforms
    343348
     349def 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   
    344529if __name__ == '__main__':  # test code
    345530
    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
    347545    cell1 = (5.03461,5.03461,13.74753,90,90,120)
    348546    center1 = 'R'
     
    387585    cellin = [5.,5.,5.,85.,85.,85.,]
    388586    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))
    390588    mat = cellList[-1]
    391589    print('test with\n',mat)
     
    395593    cellin = [3.9051,3.9051,7,99.537,99.537,100.389]
    396594    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))
    398596    mat = cellList[-1]
    399597    print('test with\n',mat)
     
    403601    cellin = [5.,5.,7.,90.,90.,120.,]
    404602    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))
    406604    mat = cellList[-1]
    407605    print('test with\n',mat)
Note: See TracChangeset for help on using the changeset viewer.