Source code for hexrd.material.jcpds

import os
import numpy as np


[docs]class JCPDS_extend(): def __init__(self, filename=None): self.a0 = 0 self.b0 = 0 self.c0 = 0 self.alpha0 = 0 self.beta0 = 0 self.gamma0 = 0 self.v0 = 0 self.k0 = 100 self.k0p = 5 # k0p at 298K self.dk0dt = 0 self.dk0pdt = 0 self.symmetry = '' self.alpha_t = 0 # alphat at 298K self.dalpha_t_dt = 0 self.file = ' ' self.name = ' ' self.version = 0 self.comments = '' if filename: self.file = filename self.read_file(self.file) self.update_v0()
[docs] def read_file(self, file): """ read a jcpds file """ self.file = file # Construct base name = file without path and without extension name = os.path.splitext(os.path.basename(self.file))[0] self.name = name # line = '', nd=0 version = 0. self.comments = [] self.DiffLines = [] version_status = '' inp = open(file, 'r').readlines() # my_list = [] # get all the text first and throw into my_list if inp[0][0] in ('2', '3', '4'): version = int(inp[0]) # JCPDS version number self.version = version header = inp[1] # header self.comments = header item = str.split(inp[2]) crystal_system = int(item[0]) if crystal_system == 1: self.symmetry = 'cubic' elif crystal_system == 2: self.symmetry = 'hexagonal' elif crystal_system == 3: self.symmetry = 'tetragonal' elif crystal_system == 4: self.symmetry = 'orthorhombic' elif crystal_system == 5: self.symmetry = 'monoclinic' elif crystal_system == 6: self.symmetry = 'triclinic' elif crystal_system == 7: self.symmetry = 'manual' # 1 cubic, 2 hexagonal, 3 tetragonal, 4 orthorhombic # 5 monoclinic, 6 triclinic, 7 manual P, d-sp input k0 = float(item[1]) k0p = float(item[2]) self.k0 = k0 self.k0p = k0p item = str.split(inp[3]) # line for unit-cell parameters if crystal_system == 1: # cubic a = float(item[0]) b = a c = a alpha = 90. beta = 90. gamma = 90. elif crystal_system == 7: # P, d-sp input a = float(item[0]) b = a c = a alpha = 90. beta = 90. gamma = 90. elif crystal_system == 2: # hexagonal a = float(item[0]) c = float(item[1]) b = a alpha = 90. beta = 90. gamma = 120. elif crystal_system == 3: # tetragonal a = float(item[0]) c = float(item[1]) b = a alpha = 90. beta = 90. gamma = 90. elif crystal_system == 4: # orthorhombic a = float(item[0]) b = float(item[1]) c = float(item[2]) alpha = 90. beta = 90. gamma = 90. elif crystal_system == 5: # monoclinic a = float(item[0]) b = float(item[1]) c = float(item[2]) beta = float(item[3]) alpha = 90. gamma = 90. elif crystal_system == 6: # triclinic a = float(item[0]) b = float(item[1]) c = float(item[2]) alpha = float(item[3]) beta = float(item[4]) gamma = float(item[5]) self.a0 = a self.b0 = b self.c0 = c self.alpha0 = alpha self.beta0 = beta self.gamma0 = gamma item = str.split(inp[4]) if self.version == 3: alpha_t = 0. else: alpha_t = float(item[0]) self.alpha_t = alpha_t version_status = 'new' elif 'VERSION' in inp[0]: jcpdsfile = open(file, 'r') while True: jcpdsline = jcpdsfile.readline() if jcpdsline == '': break jlinespl = jcpdsline.split() if jlinespl[0] == 'VERSION:': version = int(jlinespl[1]) self.version = version if jlinespl[0] == 'COMMENT:': header = ' '.join(jlinespl[1:]) self.comments = header if jlinespl[0] == 'K0:': k0 = float(jlinespl[1]) self.k0 = k0 if jlinespl[0] == 'K0P:': k0p = float(jlinespl[1]) self.k0p = k0p if jlinespl[0] == 'DK0DT:': dk0dt = float(jlinespl[1]) self.dk0dt = dk0dt if jlinespl[0] == 'DK0PDT:': dk0pdt = float(jlinespl[1]) self.dk0pdt = dk0pdt if jlinespl[0] == 'SYMMETRY:': self.symmetry = jlinespl[1].lower() if jlinespl[0] == 'A:': a = float(jlinespl[1]) self.a0 = a if jlinespl[0] == 'B:': b = float(jlinespl[1]) self.b0 = b if jlinespl[0] == 'C:': c = float(jlinespl[1]) self.c0 = c if jlinespl[0] == 'ALPHA:': alpha = float(jlinespl[1]) self.alpha0 = alpha if jlinespl[0] == 'BETA:': beta = float(jlinespl[1]) self.beta0 = beta if jlinespl[0] == 'GAMMA:': gamma = float(jlinespl[1]) self.gamma0 = gamma if jlinespl[0] == 'VOLUME:': v = float(jlinespl[1]) self.v0 = v if jlinespl[0] == 'ALPHAT:': alphat = float(jlinespl[1]) self.alpha_t = alphat if jlinespl[0] == 'DALPHATDT:': dalphatdt = float(jlinespl[1]) self.dalpha_t_dt = dalphatdt if jlinespl[0] == 'DIHKL:': pass if self.symmetry == 'cubic': self.b0 = self.a0 self.c0 = self.a0 self.alpha0 = 90. self.beta0 = 90. self.gamma0 = 90. elif self.symmetry == 'manual': self.b0 = self.a0 self.c0 = self.a0 self.alpha0 = 90. self.beta0 = 90. self.gamma0 = 90. elif self.symmetry == 'hexagonal' or self.symmetry == 'trigonal': self.b0 = self.a0 self.alpha0 = 90. self.beta0 = 90. self.gamma0 = 120. elif self.symmetry == 'tetragonal': self.b0 = self.a0 self.alpha0 = 90. self.beta0 = 90. self.gamma0 = 90. elif self.symmetry == 'orthorhombic': self.alpha0 = 90. self.beta0 = 90. self.gamma0 = 90. elif self.symmetry == 'monoclinic': self.alpha0 = 90. self.gamma0 = 90. # elif self.symmetry == 'triclinic': jcpdsfile.close() version_status = 'new' else: version_status = 'old' if version_status == 'new': self.v = self.calc_volume_unitcell()
[docs] def verify_symmetry_match(self, mat): if not self.symmetry_matches(mat): msg = ( f'The JCPDS symmetry "{self.symmetry}" does not match the ' f'symmetry of the material "{mat.latticeType}"!' ) raise SymmetryMismatch(msg)
[docs] def symmetry_matches(self, mat): return mat.latticeType == self.symmetry
@property def _lat_param_names(self): return ['a0', 'b0', 'c0', 'alpha0', 'beta0', 'gamma0'] @property def lattice_params(self): return [getattr(self, x) for x in self._lat_param_names]
[docs] def matches_material(self, mat): self.verify_symmetry_match(mat) mat_lp = [x.value for x in mat.latticeParameters] for v1, v2 in zip(mat_lp, self.lattice_params): if not np.isclose(v1, v2): return False
[docs] def write_lattice_params_to_material(self, mat): self.verify_symmetry_match(mat) mat.latticeParameters = self.lattice_params mat.reset_v0()
[docs] def write_pt_params_to_material(self, mat): self.verify_symmetry_match(mat) mat.k0 = self.k0 mat.k0p = self.k0p mat.dk0dt = self.dk0dt mat.dk0pdt = self.dk0pdt mat.alpha_t = self.alpha_t mat.dalpha_t_dt = self.dalpha_t_dt
[docs] def update_v0(self): self.v0 = self.calc_volume_unitcell()
[docs] def calc_volume_unitcell(self): '''calculate volume of the unitcell Ref: Introduction to conventional TEM Marc De Graef, Appendix 1 pg. 662 ''' ca = np.cos(np.radians(self.alpha0)) cb = np.cos(np.radians(self.beta0)) cg = np.cos(np.radians(self.gamma0)) v0 = self.a0*self.b0*self.c0 f = np.sqrt(1 - ca**2 - cb**2 - cg**2 + 2 * ca * cb * cg) return v0*f
[docs]class SymmetryMismatch(Exception): pass