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 set_locators(self, x_major=None, x_minor=None, y_major=None, y_minor=None): """Sets major and minor ticks for plot""" majors = (ut.get_default( x_major, (self.limits['x_max'] - self.limits['x_min']) // 5, ), ut.get_default( y_major, (self.limits['y_max'] - self.limits['y_min']) // 5, )) minors = (ut.get_default(x_minor, majors[0] / 5), ut.get_default(y_minor, majors[1] / 5)) if self._ax: for i, axis in enumerate((self._ax.xaxis, self._ax.yaxis)): axis.set_major_locator(plt.MultipleLocator(majors[i])) axis.set_minor_locator(plt.MultipleLocator(minors[i]))
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_chi(self, temperature=None, eigenvalues=None, eigenfunctions=None): """Calculates the susceptibility at a specified temperature.""" if eigenvalues is None and eigenfunctions is None: eigenvalues, eigenfunctions = self.get_eigenvalues_and_eigenfunctions( ) j_ops, _ = self.get_transition_probabilities(eigenfunctions) thermal = physics.thermodynamics( utils.get_default(temperature, self.temperature), eigenvalues) chi = { 'curie': { 'z': 0, 'x': 0 }, 'van_vleck': { 'z': 0, 'x': 0 }, } for row in range(eigenvalues.size): for column in range(eigenvalues.size): j_ops_square = { key: val[row, column]**2 for key, val in j_ops.items() } row_value = eigenvalues[row] column_value = eigenvalues[column] if (abs(column_value - row_value) < 0.00001 * thermal['temperature']): chi['curie']['z'] += (j_ops_square['z'] * thermal['bolzmann'][row]) chi['curie']['x'] += ( 0.25 * (j_ops_square['+'] + j_ops_square['-']) * thermal['bolzmann'][row]) else: chi['van_vleck']['z'] += (2 * j_ops_square['z'] * thermal['bolzmann'][row] / (column_value - row_value)) chi['van_vleck']['x'] += ( 0.5 * (j_ops_square['+'] + j_ops_square['-']) * thermal['bolzmann'][row] / (column_value - row_value)) coefficient = self.material.rare_earth.lande_factor**2 if thermal['temperature'] > 0: coefficient = coefficient / sum(thermal['bolzmann']) for key in ('z', 'x'): chi['curie'][key] = (coefficient / thermal['temperature'] * chi['curie'][key]) chi['van_vleck'][key] = coefficient * chi['van_vleck'][key] return chi
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 set_limits(self, x_min=None, x_max=None, y_min=None, y_max=None): """Sets limits of x and y intervals""" y_set = self.data.y_set.values() _limits = { 'x_min': (x_min, min(self.data.x)), 'x_max': (x_max, max(self.data.x)), 'y_min': (y_min, min((min(value) for value in y_set))), 'y_max': (y_max, max((max(value) for value in y_set))), } for _key, _value in _limits.items(): self.limits[_key] = ut.get_default(*_value) if self._ax: for axis in ('x', 'y'): axis_limits = { f'{axis}{lim}': self.limits[f'{axis}_{lim}'] for lim in ('min', 'max') } self._ax.__getattribute__(f'set_{axis}lim')(**axis_limits)
def get_moments(self, temperature=None, eigenvalues=None, eigenfunctions=None): """Calculates the magnetic moments of the CEF model.""" if eigenvalues is None and eigenfunctions is None: eigenvalues, eigenfunctions = self.get_eigenvalues_and_eigenfunctions( ) j_ops, _ = self.get_transition_probabilities(eigenfunctions) temperature = utils.get_default(temperature, self.temperature) thermal = physics.thermodynamics(temperature, eigenvalues) if thermal['temperature'] > 0: j_average = {'z': 0, 'x': 0} statistic_sum = sum(thermal['bolzmann']) for index in range(eigenvalues.size): j_average['z'] += (j_ops['z'][index, index] * thermal['bolzmann'][index]) j_average['x'] += ( 0.5 * (j_ops['+'][index, index] + j_ops['-'][index, index]) * thermal['bolzmann'][index]) for key, value in j_average.items(): j_average[key] = value / statistic_sum else: j_average = { 'z': (sum(j_ops['z'][eigenvalues == 0, eigenvalues == 0]) / eigenvalues[eigenvalues == 0].size), 'x': (sum(0.5 * (j_ops['+'][eigenvalues == 0, eigenvalues == 0] + j_ops['-'][eigenvalues == 0, eigenvalues == 0])) / eigenvalues[eigenvalues == 0].size) } magnetic_moment = {} for key, value in j_average.items(): magnetic_moment[key] = (self.material.rare_earth.lande_factor * value) # magnetic moments are given in units of Bohr magneton return j_average, magnetic_moment