示例#1
0
 def setUp(self):
     mock_defect_species = create_mock_defect_species(2)
     mock_defects_at_site = create_mock_defects_at_site(2)
     with patch('pyscses.site.DefectAtSite',
                autospec=True) as mock_DefectAtSite:
         mock_DefectAtSite.side_effect = mock_defects_at_site
         self.site = Site(label='A',
                          x=1.5,
                          defect_species=mock_defect_species,
                          defect_energies=[-0.2, +0.2])
示例#2
0
    def form_continuum_sites( all_sites, x_min, x_max, n_points, b, c, defect_species, limits_for_laplacian, site_labels, defect_labels ):
  
        """
        Creates a Set_of_Sites object for sites interpolated onto a regular grid, this is equivalent to assuming a continuum approximation.

        Args:
            all_sites (object): Orginal Set_of_Sites object from full data.
            x_min (float): Minimum x coordinate value defining the calculation region.
            x_max (float): Maximum x coordinate value defining the calculation region. 
            n_points (int): Number of points that the data should be interpolated on to.
            b (float): b dimension for every grid point.
            c (float): c dimension for every grid point.
            defect_species (object): Class object containing information about the defect species present in the system. 
            limits for laplacian (list): distance between the endmost sites and the midpoint of the next site outside of the calculation region for the first and last sites respectively. 
            site_labels( list ): List of strings for the different site species.
            defect_labels (list): List of strings for the different defect species.

        Returns:
            :obj:`Set_of_Sites`: Sites interpolated onto a regular grid.

	"""	    
  
        grid = np.linspace( x_min, x_max, n_points )
        limits = [grid[1] - grid[0], grid[1] - grid[0]]
        sites = []
        for label, d_label in zip(site_labels, defect_labels):
            scaling = len( all_sites.subset( label ) ) / len( grid )
            continuum_grid = Grid( grid, b, c, limits, limits_for_laplacian, all_sites.subset( label ) )
            average_energies = np.array( [ site.average_local_energy( method = 'mean' )[0] for site in all_sites.subset( label ) ] )
            new_energies = griddata( ( [ site.x for site in all_sites.subset( label ) ] ), average_energies, grid, method = 'nearest' )
            for x, e in zip( grid, new_energies):
                sites.append( Site( label, x, [ defect_species[ d_label ] ], [e], scaling = np.array( scaling ) ) )
        return Set_of_Sites( sites ), limits    
示例#3
0
    def form_continuum_sites_new(all_sites, x_min, x_max, n_points, b, c,
                                 defect_species, limits_for_laplacian,
                                 site_labels, defect_labels):

        limits = [x_min, x_max]
        grid = np.linspace(x_min, x_max, n_points)
        sites = []

        for label, d_label in zip(site_labels, defect_labels):
            scaling = len(all_sites.subset(label)) / len(grid)
            continuum_grid = Grid(grid, b, c, limits, limits_for_laplacian,
                                  all_sites.subset(label))
            average_energies = np.array([
                site.average_local_energy(method='mean')[0]
                for site in all_sites.subset(label)
            ])
            new_energies = griddata(
                ([site.x for site in all_sites.subset(label)]),
                Vo.average_energies,
                grid,
                method='nearest')
            for x, e in zip(grid, new_energies):
                sites.append(
                    Site(label,
                         x, [defect_species[d_label]], [e],
                         scaling=np.array(scaling)))

        return Set_of_Sites(sites)
示例#4
0
 def test_site_init_data_check_1(self):
     """Checks that initialising a Site object raises a ValueError if n(defect_species) != n(defect_energies)"""
     mock_defect_species = create_mock_defect_species(1)
     with patch('pyscses.site.DefectAtSite',
                autospec=True) as mock_DefectAtSite:
         with self.assertRaises(ValueError):
             site = Site(label='A',
                         x=1.5,
                         defect_species=mock_defect_species,
                         defect_energies=[-0.2, +0.2])
示例#5
0
 def test_site_init_with_mixed_mobile_and_fixed_defects(self):
     mock_defect_species = create_mock_defect_species(3)
     mock_defects_at_site = create_mock_defects_at_site(3)
     mock_defects_at_site[0].fixed = False
     mock_defects_at_site[0].mole_fraction = 0.4
     mock_defects_at_site[1].fixed = True
     mock_defects_at_site[1].mole_fraction = 0.3
     mock_defects_at_site[2].fixed = True
     mock_defects_at_site[2].mole_fraction = 0.2
     with patch('pyscses.site.DefectAtSite',
                autospec=True) as mock_DefectAtSite:
         mock_DefectAtSite.side_effect = mock_defects_at_site
         site = Site(label='C',
                     x=1.5,
                     defect_species=mock_defect_species,
                     defect_energies=[-0.2, +0.2, 0.0])
     self.assertEqual(site.fixed_defects,
                      (mock_defects_at_site[1], mock_defects_at_site[2]))
     self.assertEqual(site.mobile_defects[0], mock_defects_at_site[0])
     self.assertEqual(site.alpha, 0.5)
示例#6
0
 def test_site_is_initialised_with_optional_args(self):
     mock_defect_species = create_mock_defect_species(2)
     with patch('pyscses.site.DefectAtSite',
                autospec=True) as mock_DefectAtSite:
         mock_DefectAtSite.side_effect = create_mock_defects_at_site(2)
         site = Site(label='B',
                     x=1.5,
                     defect_species=mock_defect_species,
                     defect_energies=[-0.2, +0.2],
                     scaling=[0.5, 0.4],
                     valence=-2.0,
                     saturation_parameter=0.1)
     self.assertEqual(site.label, 'B')
     self.assertEqual(site.x, 1.5)
     self.assertEqual(site.defect_species, mock_defect_species)
     self.assertEqual(site.defect_energies, [-0.2, +0.2])
     np.testing.assert_equal(site.scaling, np.array([0.5, 0.4]))
     self.assertEqual(site.valence, -2.0)
     self.assertEqual(site.saturation_parameter, 0.1)
     self.assertEqual(site.alpha, 0.1)
示例#7
0
 def test_site_is_initialised(self):
     mock_defect_species = create_mock_defect_species(2)
     mock_defects_at_site = create_mock_defects_at_site(2)
     with patch('pyscses.site.DefectAtSite',
                autospec=True) as mock_DefectAtSite:
         mock_DefectAtSite.side_effect = mock_defects_at_site
         site = Site(label='A',
                     x=1.5,
                     defect_species=mock_defect_species,
                     defect_energies=[-0.2, +0.2])
     self.assertEqual(site.label, 'A')
     self.assertEqual(site.x, 1.5)
     self.assertEqual(site.defect_species, mock_defect_species)
     self.assertEqual(site.defect_energies, [-0.2, +0.2])
     np.testing.assert_equal(site.scaling, np.array([1.0, 1.0]))
     self.assertEqual(site.valence, 0.0)
     self.assertEqual(site.saturation_parameter, 1.0)
     self.assertEqual(site.fixed_defects, ())
     self.assertEqual(site.mobile_defects, tuple(mock_defects_at_site))
     self.assertEqual(site.alpha, 1.0)
示例#8
0
def site_from_input_file(site,
                         defect_species,
                         site_charge,
                         temperature,
                         zero_energies_less_than_kT=False):
    """
    Takes the data from the input file and converts it into a site.
    The input data file is a .txt file where each line in the file corresponds to a site. The values in each line are formatted and separated into the corresponding properties before creating a Site object for each site.

    Args:
        site (str): A line in the input file.
        defect_species (object): Class object containing information about the defect species present in the system.
        site_charge (bool): The site charge refers to the contribution to the overall charge of a site given by the original, non-defective species present at that site. True if the site charge contribution is to be included in the calculation, False if it is not to be included.
        temperature (float): Temperature in Kelvin.
        zero_energies_less_than_kT (optional(bool)): If True segregation energies with absolute values < kT will be set to zero.
            Default is False.

    Returns:
        :obj:`Site`

    """
    label = site[0]
    if site_charge == True:
        valence = float(site[1])
    if site_charge == False:
        valence = 0.0
    x = float(site[2])
    defect_labels = site[3::2]
    defect_energies = [float(e) for e in site[4::2]]
    if zero_energies_less_than_kT:
        kT = boltzmann_eV * temperature
        for d_e in defect_energies:
            if abs(d_e) < kT:
                d_e = 0.0
    return Site(label,
                x,
                [defect_species[l] for l in defect_labels],\
                defect_energies,
                valence=valence)
示例#9
0
def site_from_input_file(site, defect_species, site_charge, core, temperature):
    """
    Takes the data from the input file and converts it into a site.
    The input data file is a .txt file where each line in the file corresponds to a site. The values in each line are formatted and separated into the corresponding properties before creating a Site object for each site. 

    Args:
        site (str): A line in the input file.
        defect_species (object): Class object containing information about the defect species present in the system.
        site_charge (bool): The site charge refers to the contribution to the overall charge of a site given by the original, non-defective species present at that site. True if the site charge contribution is to be included in the calculation, False if it is not to be included.

    Returns:
        :obj:`Site`

    """
    label = site[0]
    if site_charge == True:
        valence = float(site[1])
    if site_charge == False:
        valence = 0.0
    x = float(site[2])
    defect_labels = site[3::2]
    defect_energies = [float(e) for e in site[4::2]]
    min_energy = min(defect_energies)
    if core == 'single':
        for d_e in defect_energies:
            if d_e > min_energy:
                d_e = 0.0
    if core == 'multi-site':
        for d_e in defect_energies:
            if (-boltzmann_eV * temperature) <= d_e <= (boltzmann_eV *
                                                        temperature):
                d_e = 0.0
    #defect_energies = [ 0.0 for e in site[4::2] ]
    return Site(label,
                x, [defect_species[l] for l in defect_labels],
                defect_energies,
                valence=valence)
示例#10
0
class TestSite(unittest.TestCase):
    def setUp(self):
        mock_defect_species = create_mock_defect_species(2)
        mock_defects_at_site = create_mock_defects_at_site(2)
        with patch('pyscses.site.DefectAtSite',
                   autospec=True) as mock_DefectAtSite:
            mock_DefectAtSite.side_effect = mock_defects_at_site
            self.site = Site(label='A',
                             x=1.5,
                             defect_species=mock_defect_species,
                             defect_energies=[-0.2, +0.2])

    def test_defect_with_label(self):
        self.site.defects[0].label = 'foo'
        self.site.defects[1].label = 'bar'
        self.assertEqual(self.site.defect_with_label('foo'),
                         self.site.defects[0])
        self.assertEqual(self.site.defect_with_label('bar'),
                         self.site.defects[1])

    def test_defect_with_label_2(self):
        """Checks that defect_with_label() raises a LabelError if the argument does not match any of the defect labels for this site."""
        self.site.defects[0].label = 'foo'
        self.site.defects[1].label = 'bar'
        with self.assertRaises(LabelError):
            self.site.defect_with_label('banana')

    def test_energies(self):
        self.site.defects[0].energy = -0.2
        self.site.defects[1].energy = +0.2
        self.assertEqual(self.site.energies(), [-0.2, +0.2])

    def test_probabilities_one(self):
        self.site.defects[0].boltzmann_factor = Mock(return_value=0.1)
        self.site.defects[0].mole_fraction = 0.2
        self.site.defects[0].label = 'A'
        self.site.defects[1].boltzmann_factor = Mock(return_value=0.1)
        self.site.defects[1].mole_fraction = 0.1
        self.site.defects[1].label = 'B'
        exp_A = ((0.2 * 0.1 / (1.0 + (0.2 * (0.1 - 1.0) + 0.1 * (0.1 - 1.0)))))
        exp_B = ((0.1 * 0.1 / (1.0 + (0.2 * (0.1 - 1.0) + 0.1 * (0.1 - 1.0)))))
        self.assertEqual(self.site.probabilities(phi=1.0, temp=298.0), {
            'A': exp_A,
            'B': exp_B
        })

    def test_probabilities_two(self):
        self.site.defects[0].boltzmann_factor = Mock(return_value=0.1)
        self.site.defects[0].mole_fraction = 0.2
        self.site.defects[0].label = 'A'
        self.site.defects[0].fixed = True
        self.site.alpha = 0.8
        self.site.fixed_defects = (self.site.defects[0], )
        self.site.defects[1].boltzmann_factor = Mock(return_value=0.1)
        self.site.defects[1].mole_fraction = 0.1
        self.site.defects[1].label = 'B'
        self.site.mobile_defects = (self.site.defects[1], )
        exp_A = 0.2
        exp_B = 0.8 * ((0.1 * 0.1 / (0.8 + (0.1 * (0.1 - 1.0)))))
        self.assertEqual(self.site.probabilities(phi=1.0, temp=298.0), {
            'A': exp_A,
            'B': exp_B
        })

    def test_charge(self):
        self.site.probabilities = Mock(return_value={'E': 0.1, 'D': 0.2})
        self.site.defects[0].valence = 1.0
        self.site.defects[1].valence = 2.0
        self.site.scaling = 0.5
        self.site.valence = 1.0
        expected_value = (
            (1.0 * 0.1 + 2.0 * 0.2) * 0.5 + 1.0) * fundamental_charge
        self.assertEqual(self.site.charge(phi=1.0, temp=298.0), expected_value)