Changeset 4998
- Timestamp:
- Jul 21, 2021 3:04:47 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/GSASIIconstrGUI.py
r4983 r4998 1707 1707 Opr *= -1 1708 1708 XOpr = np.inner(Opr,Trans) 1709 invOpr = nl.inv(XOpr) 1709 1710 for i,ix in enumerate(list(CSX[0])): 1710 1711 if not ix: … … 1713 1714 IndpCon = [1.0,G2obj.G2VarObj('%d::%s:%d'%(npId,name,ia))] 1714 1715 DepCons = [] 1715 for iop,opval in enumerate( XOpr[i]):1716 if opval:1716 for iop,opval in enumerate(invOpr[i]): 1717 if abs(opval) > 1e-6: 1717 1718 DepCons.append([opval,G2obj.G2VarObj('%d::%s:%s'%(opId,xnames[iop],iat))]) 1718 1719 if len(DepCons) == 1: 1719 1720 constraints['Phase'].append([DepCons[0],IndpCon,None,None,'e']) 1720 1721 elif len(DepCons) > 1: 1721 for Dep in DepCons: 1722 Dep[0] *= -1 1722 IndpCon[0] = -1. 1723 1723 constraints['Phase'].append([IndpCon]+DepCons+[0.0,None,'c']) 1724 1724 for name in ['Afrac','AUiso']: … … 1761 1761 1762 1762 # constraints on lattice parameters between phases 1763 # T = nl.inv(Trans).T 1764 # T = Trans.T 1765 # conMat = [ 1766 # [T[0,0]**2,T[0,1]**2,T[0,2]**2,T[0,0]*T[0,1],T[0,0]*T[0,2],T[0,1]*T[0,2]], 1767 # [T[1,0]**2,T[1,1]**2,T[1,2]**2,T[1,0]*T[1,1],T[1,0]*T[1,2],T[1,1]*T[1,2]], 1768 # [T[2,0]**2,T[2,1]**2,T[2,2]**2,T[2,0]*T[2,1],T[2,0]*T[2,2],T[2,1]*T[2,2]], 1769 # [2.*T[0,0]*T[1,0],2.*T[0,1]*T[1,1],2.*T[0,2]*T[1,2],T[0,0]*T[1,1]+T[0,1]*T[1,0],T[0,0]*T[1,2]+T[0,2]*T[1,0],T[0,1]*T[1,2]+T[0,2]*T[1,1]], 1770 # [2.*T[0,0]*T[2,0],2.*T[0,1]*T[2,1],2.*T[0,2]*T[2,2],T[0,0]*T[2,1]+T[0,1]*T[2,0],T[0,0]*T[2,2]+T[0,2]*T[2,0],T[0,1]*T[2,2]+T[0,2]*T[2,1]], 1771 # [2.*T[1,0]*T[2,0],2.*T[1,1]*T[2,1],2.*T[1,2]*T[2,2],T[1,0]*T[2,1]+T[1,1]*T[2,0],T[1,0]*T[2,2]+T[1,2]*T[2,0],T[1,1]*T[2,2]+T[1,2]*T[2,1]] 1772 # ] 1773 # Gnew = conMat * A: 1774 # T00**2*a0 T01**2*a1 T02**2*a2 T00*T01*a3 T00*T02*a4 T01*T02*a5 1775 # T10**2*a0 T11**2*a1 T12**2*a2 T10*T11*a3 T10*T12*a4 T11*T12*a5 1776 # T20**2*a0 T21**2*a1 T22**2*a2 T20*T21*a3 T20*T22*a4 T21*T22*a5 1777 # 2*T00*T10*a0 2*T01*T11*a1 2*T02*T12*a2 (T00*T11 + T01*T10)*a3 (T00*T12 + T02*T10)*a4 (T01*T12 + T02*T11)*a5 1778 # 2*T00*T20*a0 2*T01*T21*a1 2*T02*T22*a2 (T00*T21 + T01*T20)*a3 (T00*T22 + T02*T20)*a4 (T01*T22 + T02*T21)*a5 1779 # 2*T10*T20*a0 2*T11*T21*a1 2*T12*T22*a2 (T10*T21 + T11*T20)*a3 (T10*T22 + T12*T20)*a4 (T11*T22 + T12*T21)*a5 1780 # Generated as symbolic code using: 1781 # import sym 1782 # A0, A1, A2, A3, A4, A5 = sym.symbols('A0, A1, A2, A3, A4, A5') 1783 # G = sym.Matrix([ [A0, A3/2., A4/2.], [A3/2., A1, A5/2.], [A4/2., A5/2., A2]]) 1784 # transformation matrix 1785 # T00, T10, T20, T01, T11, T21, T02, T12, T22 = sym.symbols('T00, T10, T20, T01, T11, T21, T02, T12, T22') 1786 # Tr = sym.Matrix([ [T00, T10, T20], [T01, T11, T21], [T02, T12, T22],]) 1787 # Gnew = (Tr.T*G)*Tr 1788 1789 #print('old A',G2lat.cell2A(oldPhase['General']['Cell'][1:7])) 1790 #print('new A',G2lat.cell2A(newPhase['General']['Cell'][1:7])) 1791 1792 #this is still incorrect for hex/trig/ortho/tetragonal --> monoclinic 1793 1794 # for iAnew,Asi in enumerate(['A0','A1','A2','A3','A4','A5']): # loop through A[i] for new cell 1795 # Nparm = str(npId) + '::' + Asi 1796 # if Nparm != SetUniqAj(npId,iAnew,nSGData): 1797 # continue # skip: Ai constrained from Aj or must be zero 1798 # multDict = {} 1799 # for iAorg in range(6): 1800 # cA = conMat[iAnew][iAorg] # coeff for A[i] in constraint matrix 1801 # if abs(cA) < 1.e-8: continue 1802 # parm = SetUniqAj(opId,iAorg,oSGData) # translate to unique A[i] in original cell 1803 # if not parm: continue # must be zero 1804 # # sum coeff 1805 # if parm in multDict: 1806 # multDict[parm] += cA 1807 # else: 1808 # multDict[parm] = cA 1809 # # any non-zero multipliers? 1810 # maxMult = 0 1811 # for i in multDict: 1812 # maxMult = max(maxMult,abs(multDict[i])) 1813 # if maxMult <= 0: # Nparm computes as zero; Fix this parameter 1814 # constraints['Phase'] += [[ 1815 # [0.0,G2obj.G2VarObj(Nparm)], 1816 # None,None,'h']] 1817 # elif len(multDict) == 1: # create equivalence 1818 # key = list(multDict.keys())[0] 1819 # constraints['Phase'] += [[ 1820 # [1.0,G2obj.G2VarObj(key)], 1821 # [multDict[key],G2obj.G2VarObj(Nparm)], 1822 # None,None,'e']] 1823 # else: # create constraint 1824 # constr = [[-1.0,G2obj.G2VarObj(Nparm)]] 1825 # for key in multDict: 1826 # constr += [[multDict[key],G2obj.G2VarObj(key)]] 1827 # constr += [0.0,None,'c'] 1828 # constraints['Phase'] += [constr] 1829 1763 Aold = G2lat.cell2A(oldPhase['General']['Cell'][1:7]) 1764 if True: # debug 1765 constraints['Phase'] += G2lat.GenCellConstraints(Trans,opId,npId,Aold,True) 1766 print('old A*',G2lat.cell2A(oldPhase['General']['Cell'][1:7])) 1767 print('new A*',G2lat.cell2A(newPhase['General']['Cell'][1:7])) 1768 print('old cell',oldPhase['General']['Cell'][1:7]) 1769 print('new cell',newPhase['General']['Cell'][1:7]) 1770 else: 1771 constraints['Phase'] += G2lat.GenCellConstraints(Trans,opId,npId,Aold) 1772 1830 1773 # constraints on HAP Scale, etc. 1831 1774 for hId,hist in enumerate(UseList): #HAP - seems OK -
trunk/GSASIIlattice.py
r4974 r4998 282 282 newCell[6] = calc_V(cell2A(newCell[:6])) 283 283 return newCell 284 284 285 # code to generate lattice constraint relationships between two phases 286 # (chemical & magnetic) related by a transformation matrix. 287 288 def symInner(M1,M2): 289 '''Compute inner product of two square matrices with symbolic processing 290 Use dot product because sympy does not define an inner product primitive 291 292 This requires that M1 & M2 be two sympy objects, as created in 293 GenerateCellConstraints(). 294 295 Note that this is only used to do the symbolic math needed to generate 296 cell relationships. It is not used normally in GSAS-II. 297 ''' 298 import sympy as sym 299 prodOuter = [] 300 for i in range(3): 301 prod = [] 302 for j in range(3): 303 prod.append(M1[i,:].dot(M2[j,:])) 304 prodOuter.append(prod) 305 return sym.Matrix(prodOuter) 306 307 def GenerateCellConstraints(): 308 '''Generate unit cell constraints for transforming one set of A tensor 309 values to another using symbolic math (requires the sympy package) 310 311 Note that this is only used to do the symbolic math needed to generate 312 cell relationships. It is not used normally in GSAS-II. 313 ''' 314 import sympy as sym 315 # define A tensor for starting cell 316 A0, A1, A2, A3, A4, A5 = sym.symbols('A0, A1, A2, A3, A4, A5') 317 G = sym.Matrix([ [A0, A3/2., A4/2.], 318 [A3/2., A1, A5/2.], 319 [A4/2., A5/2., A2 ]] ) 320 # define transformation matrix 321 T00, T10, T20, T01, T11, T21, T02, T12, T22 = sym.symbols( 322 'T00, T10, T20, T01, T11, T21, T02, T12, T22') 323 Tr = sym.Matrix([ [T00, T10, T20], [T01, T11, T21], [T02, T12, T22],]) 324 # apply transform 325 newG = symInner(symInner(Tr,G),Tr).expand() 326 # define A tensor for converted cell 327 return [newG[0,0],newG[1,1],newG[2,2],2.*newG[0,1],2.*newG[0,2],2.*newG[1,2]] 328 329 def subVals(expr,A,T): 330 '''Evaluate the symbolic expressions by substituting for A0-A5 & Tij 331 332 This can be used on the cell relationships created in 333 :func:`GenerateCellConstraints` like this:: 334 335 Trans = np.array([ [2/3, 4/3, 1/3], [-1, 0, 0], [-1/3, -2/3, 1/3] ]) 336 T = np.linalg.inv(Trans).T 337 print([subVals(i,Aold,T) for i in GenerateCellConstraints()]) 338 339 :param list expr: a list of sympy expressions. 340 :param list A: This is the A* tensor as defined above. 341 :param np.array T: a 3x3 transformation matrix where, 342 Trans = np.array([ [2/3, 4/3, 1/3], [-1, 0, 0], [-1/3, -2/3, 1/3] ]) 343 (for a' = 2/3a + 4/3b + 1/3c; b' = -a; c' = -1/3, -2/3, 1/3) 344 then T = np.linalg.inv(Trans).T 345 346 Note that this is only used to do the symbolic math needed to generate 347 cell relationships. It is not used normally in GSAS-II. 348 ''' 349 import sympy as sym 350 A0, A1, A2, A3, A4, A5 = sym.symbols('A0, A1, A2, A3, A4, A5') 351 # transformation matrix 352 T00, T10, T20, T01, T11, T21, T02, T12, T22 = sym.symbols( 353 'T00, T10, T20, T01, T11, T21, T02, T12, T22') 354 vals = dict(zip([T00, T10, T20, T01, T11, T21, T02, T12, T22],T.ravel())) 355 vals.update(dict(zip([A0, A1, A2, A3, A4, A5],A))) 356 return float(expr.subs(vals)) 357 358 # some sample test code using the routines above follows:: 359 # Trans = np.array([ [2/3, 4/3, 1/3], [-1, 0, 0], [-1/3, -2/3, 1/3] ]) 360 # Mat = np.linalg.inv(Trans).T 361 # Aold = [0.05259986634758891, 0.05259986634758891, 0.005290771904550856, 0.052599866347588925, 0, 0] 362 # Anew = [0.018440738491448085, 0.03944989976069168, 0.034313054205100654, 0, -0.00513684555559103, 0] 363 # cellConstr = G2lat.GenerateCellConstraints() 364 # calcA = [G2lat.subVals(i,Aold,Mat) for i in cellConstr] 365 # print('original xform A',Anew) 366 # print('calculated xfrom A',calcA) 367 # print('input') 368 # print(' old cell',G2lat.A2cell(Aold)) 369 # print(' new cell',G2lat.A2cell(Anew)) 370 # print('derived results') 371 # print(' from eq.',G2lat.A2cell(calcA)) 372 # print(' diffs ',np.array(G2lat.A2cell(calcA)) - G2lat.A2cell(Anew)) 373 374 def fmtCellConstraints(cellConstr): 375 '''Format the cell relationships created in :func:`GenerateCellConstraints` 376 in a format that can be used to generate constraints. 377 378 Use:: 379 380 cXforms = G2lat.fmtCellConstraints(G2lat.GenerateCellConstraints()) 381 382 Note that this is only used to do the symbolic math needed to generate 383 cell relationships. It is not used normally in GSAS-II. 384 ''' 385 import re 386 import sympy as sym 387 A3, A4, A5 = sym.symbols('A3, A4, A5') 388 consDict = {} 389 for num,cons in enumerate(cellConstr): 390 cons = str(cons.factor(A3,A4,A5,deep=True).simplify()) 391 cons = re.sub('T([0-2]?)([0-2]?)',r'T[\2,\1]',cons) # Tij to T[j,i] 392 l = [] 393 for i in str(cons).split('+'): 394 if ')' in i: 395 l[-1] += ' + ' + i.strip() 396 else: 397 l.append(i.strip()) 398 print("\nA'{} = ".format(num),str(cons)) 399 consDict[num] = l 400 return consDict 401 402 cellXformRelations = {0: ['1.0*A0*T[0,0]**2', 403 '1.0*A1*T[0,1]**2', 404 '1.0*A2*T[0,2]**2', 405 '1.0*A3*T[0,0]*T[0,1]', 406 '1.0*A4*T[0,0]*T[0,2]', 407 '1.0*A5*T[0,1]*T[0,2]'], 408 1: ['1.0*A0*T[1,0]**2', 409 '1.0*A1*T[1,1]**2', 410 '1.0*A2*T[1,2]**2', 411 '1.0*A3*T[1,0]*T[1,1]', 412 '1.0*A4*T[1,0]*T[1,2]', 413 '1.0*A5*T[1,1]*T[1,2]'], 414 2: ['1.0*A0*T[2,0]**2', 415 '1.0*A1*T[2,1]**2', 416 '1.0*A2*T[2,2]**2', 417 '1.0*A3*T[2,0]*T[2,1]', 418 '1.0*A4*T[2,0]*T[2,2]', 419 '1.0*A5*T[2,1]*T[2,2]'], 420 3: ['2.0*A0*T[0,0]*T[1,0]', 421 '2.0*A1*T[0,1]*T[1,1]', 422 '2.0*A2*T[0,2]*T[1,2]', 423 '1.0*A3*(T[0,0]*T[1,1] + T[1,0]*T[0,1])', 424 '1.0*A4*(T[0,0]*T[1,2] + T[1,0]*T[0,2])', 425 '1.0*A5*(T[0,1]*T[1,2] + T[1,1]*T[0,2])'], 426 4: ['2.0*A0*T[0,0]*T[2,0]', 427 '2.0*A1*T[0,1]*T[2,1]', 428 '2.0*A2*T[0,2]*T[2,2]', 429 '1.0*A3*(T[0,0]*T[2,1] + T[2,0]*T[0,1])', 430 '1.0*A4*(T[0,0]*T[2,2] + T[2,0]*T[0,2])', 431 '1.0*A5*(T[0,1]*T[2,2] + T[2,1]*T[0,2])'], 432 5: ['2.0*A0*T[1,0]*T[2,0]', 433 '2.0*A1*T[1,1]*T[2,1]', 434 '2.0*A2*T[1,2]*T[2,2]', 435 '1.0*A3*(T[1,0]*T[2,1] + T[2,0]*T[1,1])', 436 '1.0*A4*(T[1,0]*T[2,2] + T[2,0]*T[1,2])', 437 '1.0*A5*(T[1,1]*T[2,2] + T[2,1]*T[1,2])']} 438 439 '''cellXformRelations provide the constraints on newA[i] values for a new 440 cell generated from oldA[i] values. 441 ''' 442 # cellXformRelations values were generated using:: 443 # from GSASIIlattice import fmtCellConstraints,GenerateCellConstraints 444 # cellXformRelations = fmtCellConstraints(GenerateCellConstraints()) 445 446 def GenCellConstraints(Trans,origPhase,newPhase,origA,debug=False): 447 '''Generate the constraints between two unit cells constants for a phase transformed 448 by matrix Trans. 449 450 :param np.array Trans: a 3x3 direct cell transformation matrix where, 451 Trans = np.array([ [2/3, 4/3, 1/3], [-1, 0, 0], [-1/3, -2/3, 1/3] ]) 452 (for a' = 2/3a + 4/3b + 1/3c; b' = -a; c' = -1/3, -2/3, 1/3) 453 :param int origPhase: phase id (pId) for original phase 454 :param int newPhase: phase id for the transformed phase to be constrained from 455 original phase 456 :param list origA: reciprocal cell ("A*") tensor 457 :param bool debug: If true, the constraint input is used to compute and print A* 458 and from that the direct cell for the transformed phase. 459 ''' 460 import GSASIIobj as G2obj 461 T = Mat = np.linalg.inv(Trans).T 462 Anew = [] 463 constrList = [] 464 for i in range(6): 465 constr = [[-1.0,G2obj.G2VarObj('{}::A{}'.format(newPhase,i))]] 466 mult = [] 467 for j,item in enumerate(cellXformRelations[i]): 468 const, aTerm, tTerm = item.split('*',2) 469 const = float(const) * eval(tTerm) 470 # ignore terms where either the Transform contribution is zero. 471 #if abs(const * origA[j]) > 1e-8: 472 # If A term is zero this may indicate a symmetry constraint or an 473 # accidentally zero. If required as zero then it will not be refined 474 # and we do not want to include it, but if accidentally zero we do, 475 # so include them for now and remove later. 476 if abs(const) > 1e-8: 477 constr.append([const,G2obj.G2VarObj('{}::{}'.format(origPhase,aTerm))]) 478 mult.append(const) 479 else: 480 mult.append(0) 481 constrList.append(constr + [0.0,None,'c']) 482 if debug: Anew.append(np.dot(origA,mult)) 483 if debug: 484 print('xformed A* ',Anew) 485 print('xformed cell',A2cell(Anew)) 486 return constrList 487 285 488 def TransformXYZ(XYZ,Trans,Vec): 286 489 return np.inner(XYZ,Trans)+Vec -
trunk/GSASIImapvars.py
r4983 r4998 882 882 #msg += _FormatConstraint(constrDict[rel],fixedList[rel]) 883 883 #msg += '\nNot used: ' + notused + '\n' 884 shortmsg += notused+" not used in constraint "+_FormatConstraint(constrDict[rel],fixedList[rel])884 shortmsg += notused+" not used in constraint\n\t"+_FormatConstraint(constrDict[rel],fixedList[rel])+'\n' 885 885 elif varied > 0 and varied != len(VarKeys(constrDict[rel])): 886 886 #msg += "\nNot all parameters refined in constraint:\n\t" 887 887 #msg += _FormatConstraint(constrDict[rel],fixedList[rel]) 888 888 #msg += '\nNot refined: ' + notvaried + '\n' 889 shortmsg += notvaried+" not varied in constraint "+_FormatConstraint(constrDict[rel],fixedList[rel])889 shortmsg += notvaried+" not varied in constraint\n\t"+_FormatConstraint(constrDict[rel],fixedList[rel])+'\n' 890 890 # if there were errors found, go no farther 891 891 if shortmsg and SeqHist is not None: -
trunk/GSASIIphsGUI.py
r4997 r4998 3013 3013 magId = magIds[sel] 3014 3014 if ifMag: 3015 phaseName = '%s 3015 phaseName = '%s-mag_%d'%(data['General']['Name'],magchoice['No.']) 3016 3016 else: 3017 phaseName = '%s 3017 phaseName = '%s-sub_%d'%(data['General']['Name'],magchoice['No.']) 3018 3018 newPhase = copy.deepcopy(data) 3019 3019 newPhase['ranId'] = ran.randint(0,sys.maxsize), … … 4763 4763 for pair in RMCPdict['Pairs']: 4764 4764 pairSizer.Add(G2G.ValidatedTxtCtrl(pnl,RMCPdict['Pairs'][pair],0,xmin=0.,xmax=10.,size=(50,25)),0,WACV) 4765 pairSizer.Add(wx.StaticText(pnl,label='%14s'%' Search from: '),0,WACV) 4765 pairSizer.Add(wx.StaticText(pnl,label='%14s'%' Search from: '),0,WACV) 4766 else: 4767 pairSizer.Add(wx.StaticText(pnl,label='%14s'%' Distance min: '),0,WACV) 4766 4768 for pair in RMCPdict['Pairs']: 4767 4769 pairSizer.Add(G2G.ValidatedTxtCtrl(pnl,RMCPdict['Pairs'][pair], … … 4886 4888 fileSizer.Add((-1,-1),0) 4887 4889 fileSizer.Add((-1,-1),0) 4890 elif Rfile != 'Select file': # file specified, but must not exist 4891 RMCPdict['files'][fil][0] = 'Select file' # set filSel? 4892 fileSizer.Add(wx.StaticText(G2frame.FRMC, 4893 label='Warning: file not found.\nWill be removed'),0) 4894 fileSizer.Add((-1,-1),0) 4895 fileSizer.Add((-1,-1),0) 4888 4896 else: 4889 4897 RMCPdict['files'][fil][0] = 'Select file' # set filSel? … … 5209 5217 resLine.Add(G2G.ValidatedTxtCtrl(G2frame.FRMC,RMCPdict,'Cycles',xmin=1,size=[60,25])) 5210 5218 resLine.Add(wx.StaticText(G2frame.FRMC, 5211 label=' Computation cycles of '),0,WACV)5219 label=' computation cycles of '),0,WACV) 5212 5220 RMCPdict['Steps/cycle'] = RMCPdict.get('Steps/cycle',5000) 5213 5221 resLine.Add(G2G.EnumSelector(G2frame.FRMC,RMCPdict,'Steps/cycle', … … 5854 5862 #else: 5855 5863 # batch.write(sys.exec_prefix+'/python ' + rname + '\n') 5856 batch.write(fullrmc_exec + ' ' + rname+ '\n')5864 batch.write(fullrmc_exec + ' ' + os.path.abspath(rname) + '\n') 5857 5865 batch.close() 5858 5866 if sys.platform == "darwin": … … 6008 6016 fp = open(plotFilePath,'rb') 6009 6017 fp.seek(imgDict[plt]) 6010 im = pickle.load(fp) 6011 G2plt.PlotRawImage(G2frame,im,plt) 6018 try: 6019 im = pickle.load(fp) 6020 G2plt.PlotRawImage(G2frame,im,plt) 6021 except: 6022 pass 6012 6023 fp.close() 6013 6024 else: -
trunk/GSASIIpwd.py
r4954 r4998 3100 3100 for pair in BondList: 3101 3101 e1,e2 = pair.split('-') 3102 rundata += ' ("element","{}","{}",{},{}),\n'.format( 3103 e1.strip(),e2.strip(),*BondList[pair]) 3102 d1,d2 = BondList[pair] 3103 if d1 == 0: continue 3104 if d2 == 0: 3105 print('Ignoring min distance without maximum') 3106 #rundata += ' ("element","{}","{}",{}),\n'.format( 3107 # e1.strip(),e2.strip(),d1) 3108 else: 3109 rundata += ' ("element","{}","{}",{},{}),\n'.format( 3110 e1.strip(),e2.strip(),d1,d2) 3104 3111 rundata += ' ])\n' 3105 3112 if AngleList:
Note: See TracChangeset
for help on using the changeset viewer.