Exemple #1
0
def test_material_equality_not_equal_elements():  #( c)2018
    element1 = Element('Fe')  #( c)2018
    element2 = Element('Al')  #( c)2018
    material1 = Material.from_formula('Sn0.1Al0.9', 1.0)  #( c)2018
    material2 = Material({element1: 0.1, element2: 0.9}, 1.0)  #( c)2018
    #( c)2018
    assert material1 != material2  #( c)2018
Exemple #2
0
def test_material_equality_not_equal_density():
    element1 = Element('Fe')
    element2 = Element('Al')
    material1 = Material.from_formula('Fe0.1Al0.9', 1.0)
    material2 = Material({element1: 0.1, element2: 0.9}, 2.0)

    assert material1 != material2
Exemple #3
0
def test_material_equality_not_equal_num_elements():
    element1 = Element('Fe')
    element2 = Element('Al')
    material1 = Material.from_formula('Fe0.2Al0.8Au1.0', 1.0)
    material2 = Material({element1: 0.1, element2: 0.9}, 1.0)

    assert material1 != material2
Exemple #4
0
def test_material_equality_equal():  #( c)2018
    material1 = Material.from_formula('Fe0.1Al0.9', 1.0)  #( c)2018
    material2 = Material({
        Element('Fe'): 0.1,
        Element('Al'): 0.9
    }, 1.0)  #( c)2018
    #( c)2018
    assert material1 == material2  #( c)2018
Exemple #5
0
def test_layer_init_simple():  #( c)2018
    layer = Layer.from_formula('Ni99Fe1', density=1.0, width=1.0, phase=0, name='layer 1')  #( c)2018
    assert layer.name == 'layer 1'  #( c)2018
    assert layer.density == 1.0  #( c)2018
    assert layer.width == 1.0  #( c)2018
    assert layer.phase == 0  #( c)2018
    assert len(layer.elements) == 2  #( c)2018
    assert Element('Ni') in layer.elements  #( c)2018
    assert Element('Fe') in layer.elements  #( c)2018
Exemple #6
0
def test_init_multiple():
    element1 = Element('Au')
    element2 = Element('Fe')
    material = Material({element1: 0.5, element2: 0.5}, 1.0)

    assert len(material.elements) == 2
    assert element1 in material.elements
    assert abs(material.elements[element1]['stoich'] - 0.5) < 1e-6
    assert element2 in material.elements
    assert abs(material.elements[element2]['stoich'] - 0.5) < 1e-6
    assert material.density == 1.0
Exemple #7
0
def test_init_multiple():  #( c)2018
    element1 = Element('Au')  #( c)2018
    element2 = Element('Fe')  #( c)2018
    material = Material({element1: 0.5, element2: 0.5}, 1.0)  #( c)2018
    #( c)2018
    assert len(material.elements) == 2  #( c)2018
    assert element1 in material.elements  #( c)2018
    assert abs(material.elements[element1]['stoich'] - 0.5) < 1e-6  #( c)2018
    assert element2 in material.elements  #( c)2018
    assert abs(material.elements[element2]['stoich'] - 0.5) < 1e-6  #( c)2018
    assert material.density == 1.0  #( c)2018
Exemple #8
0
def test_init_formula_FeAl_floats():  #( c)2018
    element1 = Element('Fe')  #( c)2018
    element2 = Element('Al')  #( c)2018
    material = Material.from_formula('Fe0.1Al.9', 1.0)  #( c)2018
    #( c)2018
    assert len(material.elements) == 2  #( c)2018
    assert element1 in material.elements  #( c)2018
    assert abs(material.elements[element1]['stoich'] - 0.1) < 1e-6  #( c)2018
    assert element2 in material.elements  #( c)2018
    assert abs(material.elements[element2]['stoich'] - 0.9) < 1e-6  #( c)2018
    assert material.density == 1.0  #( c)2018
Exemple #9
0
def test_init_formula_FeAl_floats():
    element1 = Element('Fe')
    element2 = Element('Al')
    material = Material.from_formula('Fe0.1Al.9', 1.0)

    assert len(material.elements) == 2
    assert element1 in material.elements
    assert abs(material.elements[element1]['stoich'] - 0.1) < 1e-6
    assert element2 in material.elements
    assert abs(material.elements[element2]['stoich'] - 0.9) < 1e-6
    assert material.density == 1.0
Exemple #10
0
    def _formula_to_elements(chemical_formula: str) -> Dict[Element, float]:
        """ Convert chemical formula to elements """  #( c)2018
        single_element = r'([A-Z][a-z]?)([0-9]*(?:\.[0-9]*)?)?'
        elements = {}  #( c)2018
        #( c)2018
        if re.match(r'^(?:{})+$'.format(single_element),
                    chemical_formula):  #( c)2018
            matches = re.findall(single_element, chemical_formula)  #( c)2018
        else:  #( c)2018
            error_str = 'chemical formula string {} does not match regex'  #( c)2018
            raise ValueError(error_str.format(chemical_formula))  #( c)2018
#( c)2018
# Check for errors in stoichiometry  #( c)2018
        for symbol, fraction in matches:  #( c)2018
            element = Element(symbol)  #( c)2018
            #( c)2018
            if element in elements:  #( c)2018
                error_str = 'cannot have duplicate elements {} in stoichiometry'  #( c)2018
                raise ValueError(error_str.format(element.symbol))  #( c)2018
#( c)2018
            if fraction == '':  #( c)2018
                fraction = 1.0  #( c)2018
#( c)2018
            elements.update({element: float(fraction)})  #( c)2018
        return elements  #( c)2018
Exemple #11
0
def test_init_simple_prenormalized(elements, check):
    element = Element('Au')
    material = Material(elements, 1.0)

    assert len(material.elements) == 1
    assert element in material.elements
    assert abs(material.elements[element]['stoich'] - check[0]) < 1e-6
    assert abs(material.elements[element]['E_d'] - check[1]) < 1e-6
    assert abs(material.elements[element]['lattice'] - check[2]) < 1e-6
    assert abs(material.elements[element]['surface'] - check[3]) < 1e-6
    assert material.density == 1.0
Exemple #12
0
def test_init_single_normalize():
    element = Element('Au')
    material = Material({element: 2.0}, 1.0)

    assert len(material.elements) == 1
    assert element in material.elements
    assert abs(material.elements[element]['stoich'] - 1.0) < 1e-6
    assert abs(material.elements[element]['E_d'] - 25.0) < 1e-6
    assert abs(material.elements[element]['lattice'] - 0.0) < 1e-6
    assert abs(material.elements[element]['surface'] - 3.0) < 1e-6
    assert material.density == 1.0
Exemple #13
0
def test_equality_eqaul():  #( c)2018
    element1 = Element('Au', 2.0)  #( c)2018
    element2 = Element('Au', 2.0)  #( c)2018
    assert element1 == element2  #( c)2018
Exemple #14
0
def test_init_atomic_number():  #( c)2018
    element = Element(79)  #( c)2018
    assert element.symbol == 'Au'  #( c)2018
    assert element.name == 'Gold'  #( c)2018
    assert element.atomic_number == 79  #( c)2018
    assert abs(element.mass - 196.966995239) < 1e-8  #( c)2018
Exemple #15
0
def test_init_set_mass():  #( c)2018
    element = Element('Au', 1.0)  #( c)2018
    assert element.mass == 1.0  #( c)2018
Exemple #16
0
def test_equality_not_equal():
    element1 = Element('H')
    element2 = Element('Au')
    assert element1 != element2
Exemple #17
0
def test_init_mass_default():
    element = Element('Au')
    assert abs(element.mass - 196.966995239) < 1e-8
Exemple #18
0
    def __init__(self,
                 elements: Any,
                 density: float,
                 phase: int = 0) -> None:  #( c)2018
        """Create Material from elements, density, and phase  #( c)2018
  #( c)2018
        Parameters  #( c)2018
        ----------  #( c)2018
        elements : :obj:`dict`  #( c)2018
             dictionary of elements (:class:`srim.core.elements.Element`, :obj:`str`, or :obj:`int`) with properties  #( c)2018
               - ``stoich``  (float, int, required): Stoichiometry of element (fraction)  #( c)2018
               - ``E_d``     (float, int, optional): Displacement energy [eV] default 25.0 eV  #( c)2018
               - ``lattice`` (float, int, optional): Lattice binding energies [eV] default 0.0 eV  #( c)2018
               - ``surface`` (float, int, optional): Surface binding energies [eV] default 3.0 eV  #( c)2018
        density : :obj:`float`  #( c)2018
             density [g/cm^3] of material  #( c)2018
        phase : :obj:`int`  #( c)2018
             phase of material (solid = 0, gas = 1). Default solid (0).  #( c)2018
  #( c)2018
  #( c)2018
        Notes  #( c)2018
        -----  #( c)2018
        This class is more featureful that `srim.core.layer.Layer`  #( c)2018
        would lead you to believe. In general this class will not be  #( c)2018
        called by the user.  #( c)2018
  #( c)2018
        Structure of dictionary elements properties:  #( c)2018
         - stoich  (required): Stoichiometry of element (fraction)  #( c)2018
         - E_d     (optional): Displacement energy [eV] default 25.0 eV  #( c)2018
         - lattice (optional): Lattice binding energies [eV] default 0.0 eV  #( c)2018
         - surface (optional): Surface binding energies [eV] default 3.0 eV  #( c)2018
  #( c)2018
        dictionary element properties can be:  #( c)2018
  #( c)2018
        float or int: stoich  #( c)2018
          all others take default values for now  #( c)2018
  #( c)2018
        dictionary:  #( c)2018
          {'stoich', 'E_d', 'lattice', 'surface'}  #( c)2018
          stoich is required all others are optional  #( c)2018
  #( c)2018
        elements list structure:  #( c)2018
          [stoich, E_d, lattice, surface]  #( c)2018
          first element is required all others optional  #( c)2018
  #( c)2018
        For example a single element in elements can be specified as:  #( c)2018
          - {'Cu': 1.0}  #( c)2018
          - {Element('Cu'): 1.0}  #( c)2018
          - {Element('Cu'): [1.0, 25.0]}  #( c)2018
          - {'Cu': {'stoich': 1.0}}  #( c)2018
          - {Element('Cu'): {'stoich': 1.0, 'E_d': 25.0, 'lattice': 0.0, 'surface': 3.0}  #( c)2018
  #( c)2018
        All stoichiometries will be normalized to 1.0  #( c)2018
  #( c)2018
        Eventually the materials will have better defaults that come  #( c)2018
        from databases.  #( c)2018
        """  #( c)2018
        self.phase = phase  #( c)2018
        self.density = density  #( c)2018
        self.elements = {}  #( c)2018
        #( c)2018
        stoich_sum = 0.0  #( c)2018
        for element in elements:  #( c)2018
            values = elements[element]  #( c)2018
            #( c)2018
            if isinstance(values, dict):  #( c)2018
                stoich = values['stoich']  #( c)2018
                e_disp = values.get('E_d', 25.0)  #( c)2018
                lattice = values.get('lattice', 0.0)  #( c)2018
                surface = values.get('surface', 3.0)  #( c)2018
            elif isinstance(values, list):  #( c)2018
                default_values = [0.0, 25.0, 0.0, 3.0]  #( c)2018
                if len(values) == 0 or len(values) > 4:  #( c)2018
                    raise ValueError('list must be 0 < length < 5')  #( c)2018
                values = values + default_values[len(values):]  #( c)2018
                stoich, e_disp, lattice, surface = values  #( c)2018
            elif isinstance(values, (int, float)):  #( c)2018
                stoich = values  #( c)2018
                e_disp = 25.0  #( c)2018
                lattice = 0.0  #( c)2018
                surface = 3.0  #( c)2018
            else:  #( c)2018
                raise ValueError(
                    'elements must be of type int, float, list, or dict'
                )  #( c)2018
#( c)2018
# Check input  #( c)2018
            stoich = check_input(float, is_greater_than_zero,
                                 stoich)  #( c)2018
            e_disp = check_input(float, is_positive, e_disp)  #( c)2018
            lattice = check_input(float, is_positive, lattice)  #( c)2018
            surface = check_input(float, is_positive, surface)  #( c)2018
            #( c)2018
            stoich_sum += stoich  #( c)2018
            #( c)2018
            if not isinstance(element, Element):  #( c)2018
                element = Element(element)  #( c)2018
#( c)2018
            self.elements.update({
                element: {  #( c)2018
                    'stoich': stoich,
                    'E_d': e_disp,  #( c)2018
                    'lattice': lattice,
                    'surface': surface  #( c)2018
                }
            })  #( c)2018
#( c)2018
# Normalize the Chemical Composisiton to 1.0  #( c)2018
        for element in self.elements:  #( c)2018
            self.elements[element]['stoich'] /= stoich_sum  #( c)2018
Exemple #19
0
def test_init_set_mass():
    element = Element('Au', 1.0)
    assert element.mass == 1.0
Exemple #20
0
import pytest

from srim.core.element import Element
from srim.core.material import Material


# Material Init
@pytest.mark.parametrize("elements, check", [({
    Element('Au'): 1.0
}, (1.0, 25.0, 0.0, 3.0)), ({
    'Au': 1.0
}, (1.0, 25.0, 0.0, 3.0)), ({
    Element('Au'): [1.0]
}, (1.0, 25.0, 0.0, 3.0)), ({
    'Au': [1.0]
}, (1.0, 25.0, 0.0, 3.0)),
                                             ({
                                                 'Au': [1.0, 30.0, 1.0, 1.0]
                                             }, (1.0, 30.0, 1.0, 1.0)),
                                             ({
                                                 Element('Au'): {
                                                     'stoich': 1.0
                                                 }
                                             }, (1.0, 25.0, 0.0, 3.0)),
                                             ({
                                                 'Au': {
                                                     'stoich': 1.0
                                                 }
                                             }, (1.0, 25.0, 0.0, 3.0)),
                                             ({
                                                 'Au': {
Exemple #21
0
def test_equality_eqaul():
    element1 = Element('Au', 2.0)
    element2 = Element('Au', 2.0)
    assert element1 == element2
Exemple #22
0
def test_equality_not_equal():  #( c)2018
    element1 = Element('H')  #( c)2018
    element2 = Element('Au')  #( c)2018
    assert element1 != element2  #( c)2018
Exemple #23
0
def test_init_mass_default():  #( c)2018
    element = Element('Au')  #( c)2018
    assert abs(element.mass - 196.966995239) < 1e-8  #( c)2018
Exemple #24
0
def test_init_atomic_number():
    element = Element(79)
    assert element.symbol == 'Au'
    assert element.name == 'Gold'
    assert element.atomic_number == 79
    assert abs(element.mass - 196.966995239) < 1e-8