This is an old revision of the document!


WPPM Macros

Paolo Scardi and co-workers have provided a set of macros for their WPPM methods in TOPAS. The macros are listed below. Save these as WPPM_macros.inc in your main TOPAS directory and add a line to your local.inc saying “#include WPPM_macros.inc”.

The publication is at: J. Appl. Cryst 2018, and the abstract says:

Macros implementing the main concepts of the whole powder pattern modelling approach have been written for TOPAS. Size and strain broadening components of the diffraction line profiles can be convolved with the instrumental profile already available among the standard commands of TOPAS. Specific macros are presented with examples of applications including plastically deformed powders and atomistic simulations. A macro is presented for the modelling of surface relaxation effects in spherical nanocrystals.

' WPPM macros by P. Scardi, C. Perez-Demydenko & C.L. Azanza Ricardo
' See also: P. Scardi, C. Perez-Demydenko, C.L. Azanza Ricardo & A. Coelho, Journal of Applied Crystallography, 2018
' The following macros can be used with any space group; additional macros specific to cubic phases are available
' email: Paolo.Scardi@unitn.it
 
macro WPPM_Sphere(RRc, RRv)
   {
      If_Prm_Eqn_Rpt(RRc, RRv, min .1 max = Min(2 Val + .3, 10000);)
      WPPM_ft_conv = 1 - 0.75*WPPM_L/RRv + 0.0625*(WPPM_L/RRv)^3 ;
 
      'WPPM_break_on_small = 1e-7;
      WPPM_L_max = 2*CeV(RRc, RRv);
      WPPM_th2_range = 55;
   }
macro WPPM_Sphere_LogNormDIST(muc, muv, sigc, sigv)
   {
      #m_argu muc
      #m_argu sigc
      If_Prm_Eqn_Rpt(muc, muv, min .1 max = Min(2 Val + .3, 100);)
      If_Prm_Eqn_Rpt(sigc, sigv, min .01 max = Min(2 Val + .01, 3);)
      WPPM_ft_conv =
         {
            def u = CeV(muc, muv);
            def sig = CeV(sigc, sigv);
            fn M(n) = 0.5 Exp(- n (u + (3 - 0.5 n) sig^2));
            fn wppm_Ln(kc) = Get(WPPM_Ln_k) + Ln(kc Get(WPPM_dL));
            fn q(n) {
               return
                  Erfc_Approx( ( wppm_Ln(1) - u - (3-n) sig^2) / (sig Sqrt(2)))
                  WPPM_L^n
                  M(n);
               }
            return q(0) - 1.5 q(1) + 0.5 q(3);
         }
         WPPM_break_on_small = 1e-7;
         WPPM_L_max 1000
         WPPM_th2_range = 30;
   }
macro getInvariant(sg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15)
   {
      #if Or(sg == 1, sg == 2); 'Triclinic, -1
         E1*H^4 + E2*K^4 + E3*L^4 + 2*(E4*H*H*K*K + E5*K*K*L*L + E6*H*H*L*L) + 4*(E7*(H^3)*K + E8*(H^3)*L + E9*H*(K^3) + E10*(K^3)*L + E11*H*(L^3) + E12*K*(L^3) + E13*H*H*K*L + E14*H*K*K*L + E15*H*K*L*L)
 
      #elseif And(sg >= 3, sg <= 15); 'Monoclinic, 2/m
         If (And(Constant(Get(al)) == 90, Constant(Get(ga)) == 90), ' unique axis b 
            E1*H^4 + E2*K^4 + E3*L^4 + 2*(E4*H*H*L*L + E5*K*K*L*L + E6*H*H*K*K) + 4*(E7*(H^3)*L + E8*H*(L^3) + E9*H*K*K*L),
            If (And(Constant(Get(al)) == 90, Constant(Get(be)) == 90), ' unique axis c 
               E1*H^4 + E2*K^4 + E3*L^4 + 2*(E4*H*H*K*K + E5*K*K*L*L + E6*H*H*L*L) + 4*(E7*(H^3)*K + E8*H*(K^3) + E9*H*K*L*L),
               "Invalid Monoclinic lattice parameters"
            )
         )
      #elseif And(sg >= 16, sg <= 74); 'Orthorhombic, mmm
         E1*H^4 + E2*K^4 + E3*L^4 + 2*(E4*H*H*K*K + E5*K*K*L*L + E6*H*H*L*L)
 
      #elseif And(sg >= 75, sg <= 88); 'Tetragonal, 4/m
         E1*(H^4 + K^4) + E2*L^4 + 2*E3*H*H*K*K + 2*E4*(H*H + K*K)*L*L + 4*E5*H*K*(H*H - K*K)
 
      #elseif And(sg >= 89, sg <= 142); 'Tetragonal, 4/mmm
         E1*(H^4 + K^4) + E2*L^4 + 2*E3*H*H*K*K + 2*E4*(H*H + K*K)*L*L
 
      #elseif And(sg >= 143, sg <= 148); 'Trigonal, -3
         #if Or(sg == 146, sg == 148); 'Trigonal space groups supporting also rhombohedral axes      
            If (Constant(Get(ga)) == 120,
               E1*(H*H - H*K + K*K)^2 + 2*E2*(H*H - H*K + K*K)*L*L + E3*L^4 + 4*E5*(H^3 - 3*H*K*K + (K^3))*L + 4*E4*H*(H - K)*K*L,
               If (Constant(Get(ga)) == 60,
                  E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 + (4/3)*E4*L*(H^3 + 3*H*H*K - K^3) + (4/3)*E5*L*(-H^3 + 3*H*K*K + K^3), ' 60deg
                  E1*(H^4 + K^4 + L^4) + 2*E2*(H*H*K*K + H*H*L*L + K*K*L*L) + 4*E3*((H^3)*K + (K^3)*L + H*(L^3)) + 4*E4*(H*(K^3) + (H^3)*L + K*(L^3))+ 4*E5*H*K*L*(H + K + L)
               )
            )
         #else      
            If (Constant(Get(ga)) == 120,
               E1*(H*H - H*K + K*K)^2 + 2*E2*(H*H - H*K + K*K)*L*L + E3*L^4 + 4*E5*(H^3 - 3*H*K*K + (K^3))*L + 4*E4*H*(H - K)*K*L,
               E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 + (4/3)*E4*L*(H^3 + 3*H*H*K - K^3) + (4/3)*E5*L*(-H^3 + 3*H*K*K + K^3) ' 60
            )
         #endif
 
      #elseif And(sg >= 149, sg <= 167); 'Trigonal, -3m
         #if Or(sg ==150, sg ==152, sg ==154, sg ==155, sg ==156, sg ==158, sg ==160, sg ==161, sg ==164, sg ==165 , sg ==166, sg ==167); 'Trigonal, -3m1
            #if Or(sg == 155, sg == 160, sg == 161, sg == 166, sg == 167); 'Trigonal space groups supporting also rhombohedral axes      
               If (Constant(Get(ga)) == 120,
                  E1*(H*H - H*K + K*K)^2 + 2*E2*L*L*(H*H - H*K + K*K) + E3*L^4 + 4*E4*H*K*L*(H - K),
                  If (Constant(Get(ga)) == 60,
                     E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 + 4*E4*H*K*L*(H + K), ' 60deg
                     E1*(H^4 + K^4 + L^4) + 2*E2*(H*H*K*K + H*H*L*L + K*K*L*L) + 4*E3*(H*K*(H*H + K*K) + H*L*(H*H + L*L) + K*L*(K*K + L*L)) + 4*E4*H*K*L*(H + K + L)
                  )
               )
            #else      
               If (Constant(Get(ga)) == 120,
                  E1*(H*H - H*K + K*K)^2 + 2*E2*L*L*(H*H - H*K + K*K) + E3*L^4 + 4*E4*H*K*L*(H - K),
                  E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 + 4*E4*H*K*L*(H + K) ' 60deg
               )
            #endif            
         #else 'Trigonal, -31m
            If (Constant(Get(ga)) == 120,
               E1*(H*H - H*K + K*K)^2 + 2*E2*L*L*(H*H - H*K + K*K) + E3*L^4 + E4*L*(4*(H^3) - 6*H*H*K - 6*H*K*K + 4*(K^3)),
               E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 + (4/3)*E4*L*(2*(H^3) + 3*H*H*K - 3*H*K*K - 2*(K^3)) ' 60deg
            )
         #endif
 
      #elseif And(sg >= 168, sg <= 194); 'Hexagonal, 6/m and 6/mmm
         If (Constant(Get(ga)) == 120,
            E1*(H*H - H*K + K*K)^2 + 2*E2*L*L*(H*H - H*K + K*K) + E3*L^4,
            E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 ' 60deg
         )
      #elseif And(sg >= 195, sg <= 230); 'Cubic, m-3 and m-3m
         E1*(H^4 + K^4 + L^4) + 2*E2*(H*H*K*K + H*H*L*L + K*K*L*L)
      #else
      #endif
   }
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6, E7, E8, E9)    
   {
      ' E1 to E9 for space groups 3 to 15 (2/m)
      Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
   }
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6) 
   {
      ' E1 to E6 for space groups 16 to 64 (mmm)
      Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
   }
 
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5) 
   {
      ' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
      Out_Invariant(file,sg, E1, E2, E3, E4, E5,,,,,,,,,,) 
   }
macro Out_Invariant(file,sg, E1, E2, E3, E4) 
   {
      ' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
      Out_Invariant(file,sg, E1, E2, E3, E4,,,,,,,,,,,) 
   }
macro Out_Invariant(file,sg, E1, E2, E3) 
   {
      ' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
      Out_Invariant(file,sg, E1, E2, E3,,,,,,,,,,,,) 
   }
macro Out_Invariant(file,sg, E1, E2) 
   {
      ' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
      Out_Invariant(file,sg, E1, E2,,,,,,,,,,,,,) 
   }
macro Out_Invariant(file,sg,E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15)
   {
      out file
         Out_String("\nCell Parameters")
         Out(Get(a), "\na =  %V;")
         Out(Get(b), "\tb = %V;")
         Out(Get(c), "\tc = %V")
         Out(Get(al), "\nalpha = %V;")
         Out(Get(be), "\tbeta = %V;")
         Out(Get(ga), "\tgamma = %V")
 
         Out_String("\n\n/")
         Out_String("*")
         Out_String(" H - K - L ------ Inv")
         Out_String(" *")
         Out_String("/")
 
         phase_out file append
            load out_record out_fmt out_eqn
            {
               "\n%4.0f" = H;
               "%4.0f" = K;
               "%4.0f" = L;
               "%12.2f" = getInvariant(sg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15) ;
            }
    }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9) 
   {
      ' E1 to E9 for space groups 3 to 15 (2/m)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6) 
   {
      ' E1 to E6 for space groups 16 to 64 (mmm)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5) 
   {
      ' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4) 
   {
      ' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3) 
   {
      ' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3,,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2) 
   {
      ' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
      WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2,,,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burgers, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15)
   {
      #m_argu rhoc
      #m_argu Rec
      If_Prm_Eqn_Rpt(rhoc, rhov, min 0 max = Min(2 Val + .0001, 0.100);)
      If_Prm_Eqn_Rpt(Rec , Rev , min 1 max = Min(2 Val + .0001, 0.100);)
 
      WPPM_ft_conv = {                   
         def invariantTerm_0 = getInvariant(wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15);
         def invariantTerm = If (invariantTerm_0 < 0, 1000, invariantTerm_0);
         def dstar = 1/(D_spacing 0.1);
         def aa = Constant(Get(a) 0.1); 
         def strainINV = invariantTerm/((aa dstar)^4);
         def rhoVal = CeV(rhoc, rhov);
         def fact = Pi burgers burgers rhoVal dstar dstar strainINV 0.01 0.5;
         def Reval = CeV(Rec, Rev);
         def eta = Abs(WPPM_L/Reval);
         def fstar = If ( eta < 1, -Ln(eta) + 7/4 - Ln(2) + eta*eta/6 - (32*eta*eta*eta)/(225*Pi), 256.0/(45.0*Pi*eta)-(11.0/24.0 + (Ln(2)+Ln(eta))/4.0)/(eta*eta));
         def result = If (WPPM_L == 0, 1, Exp(-fact*(WPPM_L*WPPM_L*fstar)));
           return result;
      }
      WPPM_break_on_small = 1e-7;
      WPPM_L_max 1000
      WPPM_th2_range = 30;
    }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9) 
   {
      ' E1 to E9 for space groups 3 to 15 (2/m)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6) 
   {
      ' E1 to E6 for space groups 16 to 64 (mmm)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5) 
   {
      ' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4) 
   {
      ' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3) 
   {
      ' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3,,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2) 
   {
      ' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
      WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2,,,,,,,,,,,,,) 
   }
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15)
   {
      #m_argu ac
      #m_argu bc
      If_Prm_Eqn_Rpt(ac, av, min 0 max = Min(2 Val + .0001, 0.100);)
      If_Prm_Eqn_Rpt(bc, bv, min 0 max = Min(2 Val + .0001, 0.100);)
      WPPM_ft_conv = {
        def invariantTerm_0 = getInvariant(wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15) ;
        def invariantTerm  = If (invariantTerm_0 < 0, 1000, invariantTerm_0);
        def dstar = 1/(D_spacing*0.1);
        def aa = Constant(Get(a) 0.1);
        def strainINV = invariantTerm/((aa*dstar)^4);
        def fact = 2*Pi*Pi*dstar*dstar*strainINV;
        def aVal = CeV(ac, av)*1e-5;
        def bVal = CeV(bc, bv)*1e-5;
        return Exp(-fact*(aVal*WPPM_L+bVal*WPPM_L*WPPM_L));
      }
      WPPM_break_on_small = 1e-7;
      WPPM_L_max 1000
      WPPM_th2_range = 30;
    }

Personal Tools