def get_chi_dependence( self, temperatures=None, eigenvalues=None, eigenfunctions=None, ): """ Calculates the susceptibility at a specified range of temperatures. """ temperatures = utils.get_default( temperatures, linspace(1, 300, 300, dtype='float64')) if eigenvalues is None and eigenfunctions is None: eigenvalues, eigenfunctions = self.get_eigenvalues_and_eigenfunctions( ) temperatures = utils.get_default( temperatures, linspace(1, 300, 300, dtype='float64')) chi_curie = { 'z': None, 'x': None, } chi_van_vleck = { 'z': None, 'x': None, } chi = { 'z': None, 'x': None, 'total': None, 'inverse': None, } for key in ('z', 'x'): chi_curie[key] = utils.get_empty_matrix(temperatures.shape) chi_van_vleck[key] = utils.get_empty_matrix(temperatures.shape) chi[key] = utils.get_empty_matrix(temperatures.shape) chi = { 'total': utils.get_empty_matrix(temperatures.shape), 'inverse': utils.get_empty_matrix(temperatures.shape), } for _, temperature in enumerate(temperatures): current_chi = self.get_chi( temperature, eigenvalues, eigenfunctions, ) for key in ('z', 'x'): chi_curie[key] = current_chi['curie'][key] chi_van_vleck[key] = current_chi['van_vleck'][key] chi[key] = chi_curie[key] + chi_van_vleck[key] chi['total'] = (chi['z'] + 2 * chi['x']) / 3 chi['inverse'] = 1 / chi['total'] return chi_curie, chi_van_vleck, chi
def get_cef_hamiltonian(self, size: int, j: float, squared_j: float): """Determines the CEF Hamiltonian based on the input parameters.""" hamiltonian = utils.get_empty_matrix(size) parameters = self.parameters for row in range(size): # row = 0...2J # mqn_1[1] = m = -J...J mqn_1 = [(row - j)**i for i in range(5)] for key in ('20', '40', '60'): hamiltonian[row, row] += (parameters[f'B{key}'] * physics.steven_operators( f'o{key}', squared_j, mqn_1, )) for degree in range(2, size - row): mqn_2 = [(row - j + degree)**i for i in range(5)] for key in ('22', '42', '62', '43', '63', '44', '64', '66'): if key[-1] == str(degree): hamiltonian[row, row + degree] += (parameters[f'B{key}'] * physics.steven_operators( f'o{key}', squared_j, mqn_1, mqn_2, )) hamiltonian[row + degree, row] = hamiltonian[row, row + degree] return hamiltonian
def get_zeeman_hamiltonian(self, size: int, j: float, squared_j: float, magnet_field: dict = None): """Determines the Zeeman terms to the Hamiltonian.""" if magnet_field is None: magnet_field = self.magnet_field hamiltonian = utils.get_empty_matrix(size) for row in range(size): # mqn_1 = m = -J...J mqn_1 = row - j hamiltonian[row, row] -= (self.material.rare_earth.lande_factor * BOHR_MAGNETON * mqn_1 * magnet_field['z']) if row < (size - 1): column = row + 1 mqn_2 = mqn_1 + 1 hamiltonian[row, column] -= (0.5 * self.material.rare_earth.lande_factor * BOHR_MAGNETON * sqrt( (squared_j - mqn_1 * mqn_2)) * magnet_field['x']) hamiltonian[column, row] = hamiltonian[row, column] return hamiltonian
def get_bolzmann_factor( self, size: int, eigenvalues, temperature=None, ): """Determines bolzmann_factor at specified temperature.""" temperature = utils.get_default(temperature or self.temperature) thermal = physics.thermodynamics(temperature, eigenvalues) bolzmann_factor = utils.get_empty_matrix(size, dimension=1) if thermal['temperature'] <= 0: bolzmann_factor[0] = 1 else: bolzmann_factor = thermal['bolzmann'] / sum(thermal['bolzmann']) return bolzmann_factor
def get_spectrum(self, energies=None, temperature=None, width_dict: dict = None, magnet_field: dict = None): """Calculates the neutron scattering cross section.""" temperature = utils.get_default(temperature, self.temperature) peaks = self.get_peaks(temperature, magnet_field) eigenvalues, _ = self.get_eigenvalues_and_eigenfunctions() if energies is None: # 501 numbers in range from -1.1*E_max to 1.1*E_max energies = linspace(-1.1 * eigenvalues[-1], 1.1 * eigenvalues[-1], 501) if width_dict is None: width_dict = {'sigma': 0.01 * (max(energies) - min(energies))} spectrum = utils.get_empty_matrix(energies.size, dimension=1) sigma = width_dict.get('sigma', None) gamma = width_dict.get('gamma', None) for peak in peaks: if sigma and not gamma: spectrum += peak[1] * physics.gaussian_normalized( energies, peak[0], sigma, ) elif gamma and not sigma: spectrum += peak[1] * physics.lorentzian_normalized( energies, peak[0], gamma, ) elif sigma and gamma: spectrum += peak[1] * physics.pseudo_voigt_normalized( energies, peak[0], sigma, gamma, ) spectrum *= 72.65 * self.material.rare_earth.lande_factor**2 return spectrum
def get_transition_probabilities( self, eigenfunctions, ): """ Determines matrix elements for dipole transitions between eigenfunctions of the total Hamiltonian. """ j = self.material.rare_earth.total_momentum_ground squared_j = j * (j + 1) size = int(2 * j + 1) j_ops = { 'z': utils.get_empty_matrix(size), '+': utils.get_empty_matrix(size), '-': utils.get_empty_matrix(size), } transition_probability = utils.get_empty_matrix(size) for row in range(size): j_ops['z'][row, row] += (eigenfunctions[size - 1, row]**2 * (size - 1 - j)) for row_j in range(size - 1): j_ops['z'][row, row] += (eigenfunctions[row_j, row]**2 * (row_j - j)) j_ops['+'][row, row] += (eigenfunctions[row_j + 1, row] * eigenfunctions[row_j, row] * sqrt(squared_j - (row_j - j) * (row_j - j + 1))) j_ops['-'][row, row] = j_ops['+'][row, row] for column in range(row + 1, size): mqn_1 = size - 1 - j j_ops['z'][row, column] += (eigenfunctions[size - 1, row] * eigenfunctions[size - 1, column] * mqn_1) for row_j in range(size - 1): mqn_1 = row_j - j j_ops['z'][row, column] += (eigenfunctions[row_j, row] * eigenfunctions[row_j, column] * mqn_1) column_j = row_j + 1 mqn_2 = column_j - j common_root = sqrt(squared_j - mqn_1 * mqn_2) j_ops['+'][row, column] += (eigenfunctions[column_j, row] * eigenfunctions[row_j, column] * common_root) j_ops['-'][row, column] += (eigenfunctions[row_j, row] * eigenfunctions[column_j, column] * common_root) transition_probability[row, column] = ( (2 * j_ops['z'][row, column]**2 + j_ops['+'][row, column]**2 + j_ops['-'][row, column]**2) / 3) j_ops['z'][column, row] = j_ops['z'][row, column] j_ops['+'][column, row] = j_ops['-'][row, column] j_ops['-'][column, row] = j_ops['+'][row, column] transition_probability[column, row] = transition_probability[row, column] return j_ops, transition_probability