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”. More details will follow along with links to tutorials and the publication.

' 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
			/* unique axis b */
			E1*H^4 + E2*L^4 + E3*K^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)
			/* 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) */
 
		#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		
				/* conventional rhombohedral setting */
				/* 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*L*(H + K + L) + 4*E4*((H^3)*K + (K^3)*L + H*(L^3)) + 4*E5*(H*(K^3) + (H^3)*L + K*(L^3)) */				
				/* conventional hexagonal setting {a,b,c}, gamma=120deg */
				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
				/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
				/* 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) */
 
			#else		
				/* conventional hexagonal setting {a,b,c}, gamma=120deg */
				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
				/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
				/* 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) */
			#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		
					/* conventional rhombohedral setting */
					/* 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*L*(H + K + L) +  4*E4*(H*K*(H*H + K*K) + H*L*(H*H + L*L) + K*L*(K*K + L*L)) */
					/* conventional hexagonal setting {a,b,c}, gamma=120deg */
					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)
					/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
					/* 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) */
 
				#else		
					/* conventional hexagonal setting {a,b,c}, gamma=120deg */
					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)
					/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
					/* 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) */
				#endif				
			#else 'Trigonal, -31m
				/* conventional hexagonal setting {a,b,c}, gamma=120deg */
				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))
				/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
				/* 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)) */
			#endif
 
		#elseif And(sg >= 168, sg <= 194); 'Hexagonal, 6/m and 6/mmm
			/* conventional hexagonal setting {a,b,c}, gamma=120deg */
			E1*(H*H - H*K + K*K)^2 + 2*E2*L*L*(H*H - H*K + K*K) + E3*L^4
			/*non conventional hexagonal setting, {a,b,c}->{a+b,b,c}, gamma=60deg*/
			/* E1*(H*H + H*K + K*K)^2 + 2*E2*L*L*(H*H + H*K + K*K) + E3*L^4 */
 
		#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)
		#endif
}
 
' E1 to E9 for space groups 3 to 15 (2/m)
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6, E7, E8, E9) {
			Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
}
 
' E1 to E6 for space groups 16 to 64 (mmm)
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6) {
			Out_Invariant(file,sg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
}
 
' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
macro Out_Invariant(file,sg, E1, E2, E3, E4, E5) {
			Out_Invariant(file,sg, E1, E2, E3, E4, E5,,,,,,,,,,) 
}
 
' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
macro Out_Invariant(file,sg, E1, E2, E3, E4) {
			Out_Invariant(file,sg, E1, E2, E3, E4,,,,,,,,,,,) 
}
 
' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
macro Out_Invariant(file,sg, E1, E2, E3) {
			Out_Invariant(file,sg, E1, E2, E3,,,,,,,,,,,,) 
}
 
' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
macro Out_Invariant(file,sg, E1, E2) {
			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) ;
         }
 }
 
 
' E1 to E9 for space groups 3 to 15 (2/m)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9) {
			WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
}
 
' E1 to E6 for space groups 16 to 64 (mmm)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6) {
			WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
}
 
' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5) {
			WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4, E5,,,,,,,,,,) 
}
 
' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4) {
			WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3, E4,,,,,,,,,,,) 
}
 
' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3) {
			WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2, E3,,,,,,,,,,,,) 
}
 
' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
macro WPPM_Strain_InvariantWilkens(rhoc, rhov, Rec, Rev, burger, wsg, E1, E2) {
			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);)
      #prm sg = wsg;
      WPPM_ft_conv = {
        def invariantTerm = getInvariant(sg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15) ;
        invariantTerm  = If (invariantTerm < 0, 1000, invariantTerm);
        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/2.0;
				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;
    }
 
 
' E1 to E9 for space groups 3 to 15 (2/m)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9) {
			WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6, E7, E8, E9,,,,,,) 
}
 
' E1 to E6 for space groups 16 to 64 (mmm)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6) {
			WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5, E6,,,,,,,,,) 
}
 
' E1 to E5 for space groups 75 to 88 (4/m) and 143 to 148 (-3)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5) {
			WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4, E5,,,,,,,,,,) 
}
 
' E1 to E4 for space groups 89 to 142 (4/mmm) and 149 to 167 (-3m)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4) {
			WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3, E4,,,,,,,,,,,) 
}
 
' E1 to E3 for space groups 168 to 194 (6/m and 6/mmm)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3) {
			WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2, E3,,,,,,,,,,,,) 
}
 
' E1 to E2 for space groups 195 to 230 (m-3 and m-3m)
macro WPPM_Strain_InvariantPAH(ac, av, bc, bv, wsg, E1, E2) {
			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);)
      #prm sg = wsg;
      WPPM_ft_conv = {
        def invariantTerm = getInvariant(sg, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15) ;
        invariantTerm  = If (invariantTerm < 0, 1000, invariantTerm);
        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