- Miller indices, d-spacing and Bragg angle in a monoclinic cell
- Elastic tensor of silicon: stability and moduli
- Structure factors and powder pattern of NaCl
- Symmetry operations: rotation angle, order and the crystallographic restriction
- Indexing the powder pattern of a cubic metal
- Debye-Waller factor of copper
- Crystallite size and microstrain: Williamson-Hall plot
- Twinning in titanium: the 10-12 twin
- X-ray crystal density and the Avogadro constant
- Lattice parameters from an orientation matrix by QR
Miller indices, d-spacing and Bragg angle in a monoclinic cell
A plane cuts the axes at 2a, 3b, 6c. Get its Miller indices, build the metric tensor of a monoclinic cell, the cell volume, the reciprocal metric tensor and the d-spacing, then the Bragg angle 2 theta for Cu K-alpha1.
#1. Plane cutting the axes at 2a, 3b, 6c: reciprocals times the lcm give the Miller indices; -> "[m]" (arith lcm "[2, 3, 6]"); -> "[h]" (arith frac_mul (arith frac_div 1 2) [m]); -> "[k]" (arith frac_mul (arith frac_div 1 3) [m]); -> "[l]" (arith frac_mul (arith frac_div 1 6) [m]); -> "[hkl]" (concat "[" [h] ", " [k] ", " [l] "]"); #2. Metric tensor of a monoclinic cell a 5.20, b 9.00, c 7.40 A, beta 104.5 deg; -> "[G]" (math calc "5.20*7.40*cos(104.5*pi/180)"); -> "[G]" (concat "[[27.04, 0, " [G] "], [0, 81, 0], [" [G] ", 0, 54.76]]"); -> "[V]" (math calc (concat "sqrt(" (matrix det [G]) ")")); #3. Reciprocal metric tensor and d-spacing: 1/d^2 = h G* h; -> "[Gs]" (matrix inverse [G]); -> "[d]" (math calc (concat "1/sqrt(" (vector dot [hkl] (matrix mul [Gs] [hkl])) ")")); #4. Bragg angle for Cu K-alpha1 1.5406 A; -> "[tt]" (math calc (concat "2*asin(1.5406/(2*" [d] "))*180/pi")); concat "Miller (" [h] " " [k] " " [l] "), gcd " (arith gcd (concat "[" [h] ", " [k] ", " [l] "]")) "; V = " (math round [V] 3) " A3; d = " (math round [d] 4) " A = " (math round (unit convert [d] "angstrom" "nm") 5) " nm; 2theta = " (math round [tt] 3) " deg"
Miller (3 2 1), gcd 1; V = 335.289 A3; d = 1.4655 A = 0.14655 nm; 2theta = 63.421 deg
- Compute the angle between two plane normals with the reciprocal metric tensor
- Index a whole powder pattern with a
forloop over hkl
Elastic tensor of silicon: stability and moduli
From the cubic stiffness constants of silicon, check the Born mechanical stability (Cholesky factor, positive eigenvalues), invert to the compliance tensor and compute the Young moduli along 100 and 111, the Poisson ratio, the bulk modulus and the Zener anisotropy.
#1. Stiffness of silicon in Voigt notation, GPa: C11 165.7, C12 63.9, C44 79.6; -> "[C]" "[[165.7, 63.9, 63.9, 0, 0, 0], [63.9, 165.7, 63.9, 0, 0, 0], [63.9, 63.9, 165.7, 0, 0, 0], [0, 0, 0, 79.6, 0, 0], [0, 0, 0, 0, 79.6, 0], [0, 0, 0, 0, 0, 79.6]]"; #2. Born stability: C positive definite, the Cholesky factor exists and all eigenvalues are > 0; -> "[L]" (json load select "rx_chol" (matrix cholesky [C]) /L); -> "[ev]" (json load select "rx_eig" (matrix eigen [C]) /values); #3. Compliance S = C^-1: Young modulus and Poisson ratio along 100; -> "[S]" (matrix inverse [C]); -> "[E100]" (math calc (concat "1/" (matrix get [S] 1 1))); -> "[nu]" (math calc (concat "-" (matrix get [S] 1 2) "/" (matrix get [S] 1 1))); #4. Young modulus along 111: 1/E = S11 - 2 S11 - S12 - S44/2 x 1/3; -> "[E111]" (math calc (concat "1/(" (matrix get [S] 1 1) "-2*(" (matrix get [S] 1 1) "-" (matrix get [S] 1 2) "-" (matrix get [S] 4 4) "/2)/3)")); #5. Bulk modulus and Zener anisotropy; -> "[B]" (math calc "(165.7+2*63.9)/3"); -> "[Az]" (math calc "2*79.6/(165.7-63.9)"); concat "eigenvalues " (string replace (string replace [ev] [_n_] "") " " "") " = C11+2C12, C11-C12, C44; L11 = " (math round (matrix get [L] 1 1) 4) "; E100 = " (math round [E100] 1) " GPa, E111 = " (math round [E111] 1) " GPa, nu = " (math round [nu] 4) ", B = " (math round [B] 1) " GPa, Zener A = " (math round [Az] 3) ", rank " (matrix rank [C]) ", trace " (matrix trace [C]) ", spectral norm " (matrix norm [C]) ", cond " (math round (matrix cond [C]) 3)
eigenvalues [293.5,101.8,101.8,79.6,79.6,79.6] = C11+2C12, C11-C12, C44; L11 = 12.8725; E100 = 130.1 GPa, E111 = 187.9 GPa, nu = 0.2783, B = 97.8 GPa, Zener A = 1.564, rank 6, trace 735.9, spectral norm 293.5, cond 3.687
- Try an unstable set C12 > C11:
matrix choleskythen fails - Average the moduli of a polycrystal (Voigt and Reuss) from C and S
Structure factors and powder pattern of NaCl
Sum the structure factor F = sum f exp(2 pi i h.x) over the 8 ions of the NaCl cell for the first reflections, then plot the powder pattern with multiplicity, Lorentz-polarisation and a simple fall-off: the odd reflections are weak (|F| = 4 (fCl - fNa)).
#1. NaCl, a = 5.640 A: Na+ 10 electrons on the fcc sites, Cl- 18 electrons shifted by a/2; -> "[atoms]" "10,0,0,0;10,0.5,0.5,0;10,0.5,0,0.5;10,0,0.5,0.5;18,0.5,0,0;18,0,0.5,0;18,0,0,0.5;18,0.5,0.5,0.5"; -> "[refl]" "1,1,1,8;2,0,0,6;2,2,0,12;3,1,1,24;2,2,2,8;4,0,0,6;3,3,1,24;4,2,0,24"; -> "[tt]" ""; -> "[I]" ""; -> "[txt]" ""; for (-> "[r]" 1) (<= [r] (atom size [refl] ";")) (++ "[r]") { -> "[hkl]" (atom get [refl] [r] ";"); -> "[h]" (atom get [hkl] 1 ","); -> "[k]" (atom get [hkl] 2 ","); -> "[l]" (atom get [hkl] 3 ","); #2. Structure factor F = sum f exp 2 pi i h.x; -> "[F]" "0"; for (-> "[j]" 1) (<= [j] (atom size [atoms] ";")) (++ "[j]") { -> "[at]" (atom get [atoms] [j] ";"); -> "[ph]" (math calc (concat "2*pi*(" [h] "*" (atom get [at] 2 ",") "+" [k] "*" (atom get [at] 3 ",") "+" [l] "*" (atom get [at] 4 ",") ")")); -> "[F]" (complex add [F] (complex mul (atom get [at] 1 ",") (complex exp (concat [ph] "i")))); }; #3. Intensity = multiplicity x Lorentz-polarisation x F F* x fall-off B = 3 A2; -> "[F2]" (complex re (complex mul [F] (complex conj [F]))); -> "[th]" (math calc (concat "asin(1.5406*sqrt(" [h] "^2+" [k] "^2+" [l] "^2)/(2*5.640))")); -> "[lp]" (math calc (concat "(1+cos(2*" [th] ")^2)/(sin(" [th] ")^2*cos(" [th] "))")); -> "[tt]" (concat [tt] "," (math round (math calc (concat "2*" [th] "*180/pi")) 2)); -> "[I]" (concat [I] "," (math round (math calc (concat (atom get [hkl] 4 ",") "*" [lp] "*" [F2] "*exp(-6*(sin(" [th] ")/1.5406)^2)")) 0)); -> "[txt]" (concat [txt] " " [h] [k] [l] " " (math round (complex abs [F]) 0) "/" (math round (complex arg [F]) 2)); }; #4. Bar chart of the normalised intensities; -> "[Iv]" (string replace (concat "[" [I] "]") "[," "["); -> "[In]" (vector scale [Iv] (math calc (concat "100/" (stat max [Iv])))); plot chart (concat "{\"title\": \"NaCl, Cu Ka, |F|/phase:" [txt] "\", \"x_label\": \"2 theta (deg)\", \"y_label\": \"I (%)\", \"series\": [{\"name\": \"NaCl\", \"type\": \"bars\", \"x\": " (string replace (concat "[" [tt] "]") "[," "[") ", \"y\": " [In] "}]}")
The chart is shown in the Plot tab of the editor.
- Replace Na by K (KCl): fK+ = fCl- and the odd reflections vanish
- Use form factors depending on sin(theta)/lambda with
num interpolatein a table
Symmetry operations: rotation angle, order and the crystallographic restriction
Three symmetry operations of a hexagonal crystal are given as integer matrices in the a, b, c basis. Their determinant tells proper from improper, the trace gives the rotation angle (1 + 2cos theta), and the smallest power equal to the identity gives the order; a 5-fold axis is impossible.
#1. Symmetry operations given as matrices in the hexagonal basis a, b, c; -> "[R3]" "[[0, -1, 0], [1, -1, 0], [0, 0, 1]]"; -> "[R6]" "[[1, -1, 0], [1, 0, 0], [0, 0, 1]]"; -> "[M]" "[[0, -1, 0], [-1, 0, 0], [0, 0, 1]]"; #2. Determinant +1 proper rotation, -1 improper, trace = 1 + 2 cos theta for a rotation; -> "[out]" ""; -> "[ops]" "R3 R6 M"; for (-> "[i]" 0) (< [i] 3) (++ "[i]") { -> "[name]" (string substring [ops] (* [i] 3) (+ (* [i] 3) 2)); -> "[W]" [R3]; if (== [i] 1) {-> "[W]" [R6];}; if (== [i] 2) {-> "[W]" [M];}; -> "[d]" (matrix det [W]); -> "[th]" (math round (math rad_to_deg (math acos (math calc (concat "(" [d] "*" (matrix trace [W]) "-1)/2")))) 6); #Order n: smallest power giving the identity, a finite-order matrix with trace 3; -> "[n]" 1; while (!= (matrix trace (matrix pow [W] [n])) 3) {++ "[n]";}; -> "[out]" (concat [out] [name] ": det " [d] ", angle " [th] " deg, order " [n] "; "); }; #3. Crystallographic restriction: 2 cos theta must be an integer, only n = 1, 2, 3, 4, 6; concat [out] "for n = 5, 2cos(2pi/5) = " (math round (math calc "2*cos(2*pi/5)") 4) " is not an integer: no 5-fold axis in a lattice"
R3: det 1, angle 120 deg, order 3; R6: det 1, angle 60 deg, order 6; M: det -1, angle 180 deg, order 2; for n = 5, 2cos(2pi/5) = 0.618 is not an integer: no 5-fold axis in a lattice
- Multiply two operations with
matrix multo find the third one of the group - Transform the matrix to the Cartesian basis with the metric:
matrix inverseandmatrix mul
Indexing the powder pattern of a cubic metal
Five peaks of a copper powder pattern measured with Cu K-alpha1: the ratios of sin^2 theta give the integers h^2+k^2+l^2 (3, 4, 8, 11, 12, so FCC), each peak gives a lattice parameter, and the cell with 4 atoms gives the X-ray density.
#1. Powder pattern of a cubic metal with Cu K-alpha1, 2theta of the first five peaks in degrees; -> "[lambda]" 1.5406; -> "[tt]" "[43.30, 50.43, 74.13, 89.93, 95.14]"; json load "rx_tu1_pk" [tt]; #2. sin^2 theta of each peak divided by the first one, times 3: FCC gives 3 4 8 11 12, BCC 2 4 6 8 10; -> "[s1]" (math calc (concat "sin(" (json select "rx_tu1_pk" "/[0]") "*pi/360)^2")); -> "[N]" "["; -> "[a]" "["; for (-> "[i]" 0) (< [i] 5) (++ "[i]") { -> "[th]" (math calc (concat (json select "rx_tu1_pk" (concat "/[" [i] "]")) "*pi/360")); -> "[hkl2]" (math round (math calc "3*sin([th])^2/[s1]") 0); -> "[N]" (concat [N] [hkl2] ","); #Lattice parameter a = lambda.sqrt of h2+k2+l2 over 2 sin theta; -> "[a]" (concat [a] (math calc "[lambda]*sqrt([hkl2])/(2*sin([th]))") ","); }; -> "[a]" (concat (string substring [a] 0 (- (string length [a]) 1)) "]"); #3. Mean lattice parameter, then X-ray density with Z = 4 atoms of Cu per cell; -> "[am]" (stat mean [a]); -> "[rho]" (math calc (concat "4*63.546/(" (const get "NA") "*([am]*1e-8)^3)")); -> "[N]" (concat (string substring [N] 0 (- (string length [N]) 1)) "]"); concat "h2+k2+l2 = " [N] ": 111 200 220 311 222, h k l unmixed, FCC; a = " (math round [am] 4) " A, spread " (math round_sig (stat pstddev [a]) 2) " A; density = " (math round [rho] 3) " g/cm3"
h2+k2+l2 = [3,4,8,11,12]: 111 200 220 311 222, h k l unmixed, FCC; a = 3.6156 A, spread 0.00062 A; density = 8.93 g/cm3
- Correct the zero shift by fitting a against cos^2 theta / sin theta with
stat fit(Nelson-Riley) - Get the crystallite size from the peak widths with the Scherrer equation
Debye-Waller factor of copper
From the Debye temperature of copper, the script computes the Debye function, the Debye-Waller factor B with the Planck, Boltzmann and atomic mass constants, the mean square displacement and the intensity kept by the 111, 200 and 400 reflections.
#1. Copper at 293 K, Debye temperature 343 K, M = 63.546 u: constants h, kB and u; -> "[h]" (string replace (atom get (constant physics_planck) 1 " ") "(" ""); -> "[kB]" (string replace (atom get (constant physics_k) 1 " ") "(" ""); -> "[m]" (math calc (concat "63.546*" (string replace (atom get (constant physics_amu) 1 " ") "(" ""))); -> "[T]" 293; -> "[TD]" 343; -> "[x]" (math calc "[TD]/[T]"); #2. Debye function phi x = 1/x integral of t / e^t - 1 from 0 to x; -> "[phi]" (math calc (concat (num integrate "t/(exp(t)-1)" "t" 0 [x]) "/[x]")); #3. Debye-Waller factor B = 6 h^2 T / m kB TD^2 x phi x / x + 1/4, in angstrom^2; -> "[B]" (math calc "6*[h]^2*[T]/([m]*[kB]*[TD]^2)*([phi]/[x]+0.25)*1e20"); #4. Intensity lost by thermal vibration exp -2B s^2, s = 1/2d, a = 3.615 A; -> "[out]" ""; for (-> "[i]" 1) (<= [i] 3) (++ "[i]") { -> "[hkl]" (atom get "111,200,400" [i] ","); -> "[d]" (math calc (concat "3.615/sqrt(" (atom get "3,4,16" [i] ",") ")")); -> "[out]" (concat [out] " " [hkl] ": " (math round (math calc (concat "exp(-2*[B]/(4*" [d] "^2))*100")) 1) " %"); }; concat "phi(x) = " (math round [phi] 4) ", B = " (math round [B] 3) " A2, mean square displacement u2 = B/8 pi^2 = " (math round (math calc "[B]/(8*pi^2)") 5) " A2; intensity kept:" [out]
phi(x) = 0.7449, B = 0.399 A2, mean square displacement u2 = B/8 pi^2 = 0.00505 A2; intensity kept: 111: 95.5 % 200: 94.1 % 400: 78.3 %
- Go back from measured intensities at two temperatures to the Debye temperature with
num solve - Add the zero-point term at 0 K
Crystallite size and microstrain: Williamson-Hall plot
Six peaks of a CeO2 nanopowder are corrected for the instrument width. The script compares the Scherrer size of the first peak with a Williamson-Hall least-squares line, which separates size and microstrain.
#1. CeO2 nanopowder, Cu Ka 1.5406 A: 2 theta and FWHM in degrees, instrument FWHM 0.07 deg; -> "[tt]" "28.55,33.08,47.48,56.33,69.40,76.70"; -> "[fw]" "0.452,0.478,0.556,0.613,0.715,0.786"; -> "[X]" ""; -> "[Y]" ""; for (-> "[i]" 1) (<= [i] 6) (++ "[i]") { -> "[th]" (math calc (concat (atom get [tt] [i] ",") "/2*pi/180")); #2. Sample broadening in radians, Gaussian correction b^2 - bi^2; -> "[b]" (math calc (concat "sqrt(" (atom get [fw] [i] ",") "^2-0.07^2)*pi/180")); #3. Williamson-Hall: b cos theta = K lambda / D + 4 eps sin theta, with cos = 1/sec; -> "[Y]" (concat [Y] "," (math calc (concat [b] "/" (math sec [th])))); -> "[X]" (concat [X] ",[1," (math calc (concat "4*" (math sin [th]))) "]"); if (== [i] 1) { -> "[D1]" (math calc (concat "0.9*1.5406/(" [b] "/" (math sec [th]) ")/10")); -> "[tan1]" (math tan [th]); -> "[b1]" [b]; }; }; #4. Least squares line: intercept K lambda / D, slope = microstrain; -> "[fit]" (matrix solve (concat "[" (string substr [X] 1) "]") (concat "[" (string substr [Y] 1) "]")); -> "[D]" (math calc (concat "0.9*1.5406/" (matrix get (concat "[" [fit] "]") 1 1) "/10")); -> "[eps]" (matrix get (concat "[" [fit] "]") 1 2); concat "Scherrer on 111 alone: D = " (math round [D1] 1) " nm; Williamson-Hall: D = " (math round [D] 1) " nm, strain = " (math round (math calc "[eps]*100") 3) " %, strain part of the 111 width b_strain = 4 eps tan theta = " (math round (math calc "4*[eps]*[tan1]/[b1]*100") 1) " %"
Scherrer on 111 alone: D = 18.4 nm; Williamson-Hall: D = 25.2 nm, strain = 0.208 %, strain part of the 111 width b_strain = 4 eps tan theta = 27.1 %
- Use Lorentzian profiles: subtract the widths linearly
- Draw the Williamson-Hall plot with
plot fit
Twinning in titanium: the 10-12 twin
In hexagonal alpha-Ti, the script builds the Cartesian basis, the normal of the (10-12) twin plane from the reciprocal basis, the angle with the c axis using atan2, the 85 degree c-axis rotation, the twinning shear and the d-spacing.
#1. alpha-Ti, hexagonal a = 2.951 A, c = 4.684 A: Cartesian basis a1, a2, c; -> "[a]" 2.951; -> "[c]" 4.684; -> "[g]" (math calc "[c]/[a]"); -> "[Bm]" (concat "[[" [a] ", " (math calc "-[a]/2") ", 0], [0, " (math calc "[a]*sqrt(3)/2") ", 0], [0, 0, " [c] "]]"); #2. Normal of the twin plane 10-12 = 1 0 2 in 3 indices: h a* + k b* + l c*, rows of B^-1; -> "[Bi]" (matrix inverse [Bm]); -> "[n]" (vector add (vector add (matrix row [Bi] 1) (vector scale (matrix row [Bi] 2) 0)) (vector scale (matrix row [Bi] 3) 2)); -> "[cz]" "[0, 0, 1]"; #3. Angle plane normal / c axis with atan2 of |n x c| and n.c, robust near 0 and 90 deg; -> "[ang]" (math atan2 (vector norm (vector cross [n] [cz])) (vector dot [n] [cz])); #4. Twinning shear of 10-12 s = gamma^2 - 3 / sqrt 3 gamma, d-spacing 1/|n|; -> "[s]" (math calc "([g]^2-3)/(sqrt(3)*[g])"); concat "c/a = " (math round [g] 4) "; angle between (10-12) normal and c = " (math round (math calc "[ang]*180/pi") 2) " deg, so the twin rotates c by " (math round (math calc "2*[ang]*180/pi") 2) " deg; twin shear s = " (math round [s] 4) " (c/a < sqrt 3: sign " (math signum [s]) "); d(10-12) = " (math round (math calc (concat "1/" (vector norm [n]))) 4) " A, check " (math round (math calc (concat "1/" (math hypot (math calc "2/(sqrt(3)*[a])") (math calc "2/[c]")))) 4) " A"
c/a = 1.5873; angle between (10-12) normal and c = 42.5 deg, so the twin rotates c by 85 deg; twin shear s = -0.1748 (c/a < sqrt 3: sign -1); d(10-12) = 1.7266 A, check 1.7266 A
- Compare with magnesium, c/a = 1.624
- Compute the angle between [2-1-10] and [10-10] directions
X-ray crystal density and the Avogadro constant
The XRCD method counts the atoms of a 28Si sphere: N_A = 8 M / (rho a^3). The script compares the result with the exact SI 2019 value (the same in 'constant' and 'const get'), shows the sensitivity to a, and solves the reverse problem for NaCl and iron with cube roots.
#1. XRCD route to the Avogadro constant: silicon sphere density and molar mass of enriched 28Si; -> "[rho]" 2320.070; -> "[M]" 27.97697e-3; -> "[a]" 543.0996e-12; #2. N_A = 8 M / rho a^3, 8 atoms in the diamond cell, against the exact SI 2019 value; -> "[NA]" (math calc "8*[M]/([rho]*[a]^3)"); -> "[cst]" (string regexp_extract (constant physics_n) "[-0-9.]+E?[-0-9]*" 0); -> "[si]" (const get "NA"); #3. Reverse problem: lattice parameter of NaCl from its density 2165 kg/m3, Z = 4, cube root; -> "[aN]" (math cbrt (math calc (concat "4*58.443e-3/(2165*" [si] ")"))); #4. Same with nroot for a hypothetical bcc iron cell of density 7874, Z = 2; -> "[aFe]" (math nroot (math calc (concat "2*55.845e-3/(7874*" [si] ")")) 3); -> "[da]" (math calc "-3*0.1e-15/[a]*1e9"); concat "N_A = " (math round_sig (math calc "[NA]/1e23") 9) "E23 /mol, SI 2019 " [cst] " = " [si] " (gap " (math round (math calc "([NA]-[si])/[si]*1e9") 1) " ppb, an error of only 0.1 fm on a shifts N_A by " (math round [da] 0) " ppb); a(NaCl) = " (math round (math calc "[aN]*1e10") 4) " A, a(Fe) = " (math round (math calc "[aFe]*1e10") 4) " A"
N_A = 6.02214387E23 /mol, SI 2019 6.02214076E23 = 6.02214076E23 (gap 517.1 ppb, an error of only 0.1 fm on a shifts N_A by -552 ppb); a(NaCl) = 5.6389 A, a(Fe) = 2.8665 A
- Propagate the uncertainties of rho, M and a with
num uncertainty - Get the density of copper from a = 3.615 A
Lattice parameters from an orientation matrix by QR
A diffractometer gives the orientation matrix UB of a monoclinic crystal in the lab frame. A QR decomposition separates the rotation Q from the upper-triangular cell matrix R, from which the script reads a, b, c, beta and the volume.
#1. Orientation matrix of a monoclinic crystal on a diffractometer: cell 5.20, 7.10, 9.40 A, beta 104 deg, rotated in the lab frame; -> "[be]" (math calc "104*pi/180"); -> "[B0]" (concat "[[5.20, 0, " (math calc (concat "9.40*" (math cos [be]))) "], [0, 7.10, 0], [0, 0, " (math calc (concat "9.40*" (math sin [be]))) "]]"); -> "[Rz]" (concat "[[" (math cos 0.5) ", " (math calc "-sin(0.5)") ", 0], [" (math sin 0.5) ", " (math cos 0.5) ", 0], [0, 0, 1]]"); -> "[Rx]" (concat "[[1, 0, 0], [0, " (math cos 0.3) ", " (math calc "-sin(0.3)") "], [0, " (math sin 0.3) ", " (math cos 0.3) "]]"); -> "[UB]" (matrix mul (matrix mul [Rz] [Rx]) [B0]); #2. QR splits UB into a rotation Q and an upper triangular cell matrix R, the standard setting; -> "[R]" (json load select "rx_p4b_ub" (matrix qr [UB]) /R); -> "[Q]" (json select "rx_p4b_ub" /Q); json unload "rx_p4b_ub"; #3. Cell parameters back from the columns of R, angle beta from the dot product; -> "[ra]" (matrix col [R] 1); -> "[rb]" (matrix col [R] 2); -> "[rc]" (matrix col [R] 3); -> "[beta]" (math calc (concat "acos(" (vector dot [ra] [rc]) "/(" (vector norm [ra]) "*" (vector norm [rc]) "))*180/pi")); #4. Volume = abs det R = abs det UB, and Q is orthogonal: det = +1 or -1, a Householder reflection; concat "a = " (math round (vector norm [ra]) 4) ", b = " (math round (vector norm [rb]) 4) ", c = " (math round (vector norm [rc]) 4) " A, beta = " (math round [beta] 3) " deg; V = " (math round (math abs (matrix det [R])) 3) " A3 = " (math round (math abs (matrix det [UB])) 3) "; det Q = " (math round (matrix det [Q]) 6)
a = 5.2, b = 7.1, c = 9.4 A, beta = 104 deg; V = 336.739 A3 = 336.739; det Q = -1
- Flip the sign of a row of R to get a proper rotation with det Q = +1
- Build the reciprocal cell from R^-1 transposed
