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
示例#2
0
 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
示例#6
0
 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