Ignore:
Timestamp:
Jan 27, 2019 4:30:39 PM (4 years ago)
Author:
toby
Message:

generalized restraints completed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIstrMath.py

    r3801 r3802  
    303303
    304304def penaltyFxn(HistoPhases,calcControls,parmDict,varyList):
    305     'Needs a doc string'
     305    'Compute user-supplied and built-in restraint functions'
    306306    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
    307307    pNames = []
     
    327327        names = [['Bond','Bonds'],['Angle','Angles'],['Plane','Planes'],
    328328            ['Chiral','Volumes'],['Torsion','Torsions'],['Rama','Ramas'],
    329             ['ChemComp','Sites'],['Texture','HKLs'],]
     329            ['ChemComp','Sites'],['Texture','HKLs'],['General','General'],]
    330330        for name,rest in names:
    331331            pWsum[name] = 0.
     
    335335            itemRest = phaseRest[name]
    336336            if itemRest[rest] and itemRest['Use']:
    337                 wt = itemRest['wtFactor']
     337                wt = itemRest.get('wtFactor',1.)
    338338                if name in ['Bond','Angle','Plane','Chiral']:
    339339                    for i,[indx,ops,obs,esd] in enumerate(itemRest[rest]):
     
    405405                                pWsum[name] += wt*(Z2/esd2)**2
    406406                                pWnum[name] += 1
     407                elif name == 'General':
     408                    for i,(eq,obs,esd) in enumerate(itemRest[rest]):
     409                        pNames.append(str(pId)+':'+name+':'+str(i))
     410                        calcobj = G2obj.ExpressionCalcObj(eq)
     411                        calcobj.SetupCalc(parmDict)
     412                        calc = calcobj.EvalExpression()
     413                        pVals.append(obs-calc)
     414                        pWt.append(wt/esd**2)                   
     415                        pWsum[name] += wt*((obs-calc)/esd)**2
     416                        pWnum[name] += 1
    407417       
    408418    for phase in Phases:
     
    458468   
    459469def penaltyDeriv(pNames,pVal,HistoPhases,calcControls,parmDict,varyList):
    460     'Needs a doc string'
     470    '''Compute derivatives on user-supplied and built-in restraint
     471    (penalty) functions
     472
     473    where pNames is list of restraint labels
     474
     475    returns pDerv with partial derivatives by variable# in varList and
     476       restraint# in pNames (pDerv[variable#][restraint#])
     477    '''
    461478    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
    462479    pDerv = np.zeros((len(varyList),len(pVal)))
     480    for pName in pNames: # loop over restraints
     481        if 'General' == pName.split(':')[1]:
     482            # initialize for General restraint(s) here
     483            GeneralInit = True
     484            parmDict0 = parmDict.copy()
     485            # setup steps for each parameter
     486            stepDict = {}
     487            for parm in varyList:
     488                if parm.split(':')[2].startswith('dA'):
     489                    stepDict[parm] = 1e-5
     490                elif True:
     491                    stepDict[parm] = 1e-4
     492            break
    463493    for phase in Phases:
    464494#        if phase not in restraintDict:
     
    484514            'ChemComp':'Sites','Texture':'HKLs'}
    485515        lasthkl = np.array([0,0,0])
    486         for ip,pName in enumerate(pNames):
     516        for ip,pName in enumerate(pNames): # loop over restraints
    487517            pnames = pName.split(':')
    488518            if pId == int(pnames[0]):
     
    546576                            dNames += [str(pId)+'::'+SHname]
    547577                            deriv.append(-ODFln[SHname][0]*Ksl/SHCoef[SHname])
     578                elif name == 'General':
     579                    deriv = []
     580                    dNames = []
     581                    eq,obs,esd = itemRest[name][id]
     582                    calcobj = G2obj.ExpressionCalcObj(eq)
     583                    parmlist = list(eq.assgnVars.values()) # parameters used in this expression
     584                    for parm in parmlist: # expand list if any parms are determined by constraints
     585                        if parm in G2mv.dependentVars:
     586                            parmlist += G2mv.independentVars
     587                            break
     588                    for ind,var in enumerate(varyList):
     589                        drv = 0
     590                        if var in parmlist:
     591                            step = stepDict.get(var,1e-5)
     592                            calc = []
     593                            # apply step to parameter
     594                            oneparm = True
     595                            for s in -step,2*step:
     596                                parmDict[var] += s
     597                                # extend shift if needed to other parameters
     598                                if var in G2mv.independentVars:
     599                                    G2mv.Dict2Map(parmDict,[])
     600                                    oneparm = False
     601                                elif var in G2mv.dependentVars:
     602                                    G2mv.Map2Dict(parmDict,[])
     603                                    oneparm = False
     604                                if 'RB' in var:
     605                                    ApplyRBModels(parmDict,Phases,rigidbodyDict)
     606# test
     607                                    oneparm = False
     608                                calcobj.SetupCalc(parmDict)
     609                                calc.append(calcobj.EvalExpression())
     610                            drv = (calc[1]-calc[0])*.5/step
     611                            # restore the dict
     612                            if oneparm:
     613                                parmDict[var] = parmDict0[var]
     614                            else:
     615                                parmDict = parmDict0.copy()
     616                        else:
     617                            drv = 0
     618                        pDerv[ind][ip] = drv
     619                # Add derivatives into matrix, if needed
    548620                for dName,drv in zip(dNames,deriv):
    549621                    try:
     
    821893    if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict:
    822894        Flack = 1.-2.*parmDict[phfx+'Flack']
    823     time0 = time.time()
     895#    time0 = time.time()
    824896#reflection processing begins here - big arrays!
    825897    iBeg = 0
     
    14731545        for iel,El in enumerate(refDict['FF']['El']):
    14741546            refDict['FF']['FF'].T[iel] = G2el.ScatFac(FFtables[El],SQ)
    1475     time0 = time.time()
     1547#    time0 = time.time()
    14761548#reflection processing begins here - big arrays!
    14771549    iBeg = 0
     
    16251697            for iel,El in enumerate(refDict['FF']['El']):
    16261698                refDict['FF']['FF'].T[iel] = G2el.ScatFac(FFtables[El],SQ)
    1627     time0 = time.time()
     1699#    time0 = time.time()
    16281700#reflection processing begins here - big arrays!
    16291701    iBeg = 0
Note: See TracChangeset for help on using the changeset viewer.