Exemple #1
0
def test_ionization_shells():
    """Tests that the ionization shells have the correct shape and units."""
    settings = read_input('data/materials/pmma.yaml')
    if not check_settings(settings, cstool_model):
        raise ValueError("Parsed settings do not conform the model.")

    shells = ionization_shells(settings)

    assert len(shells) > 0
    for shell in shells:
        assert shell['B'].dimensionality == units('eV').dimensionality
        assert shell['K'].dimensionality == units('eV').dimensionality
        assert shell['cs'].dimensionality == units('m^2').dimensionality
Exemple #2
0
def branch_loss(c_s, alpha, lattice, T):
    """Compute the net average energy loss of phonons.

    :param c_s_lo: speed of sound for longitudinal mode (m/s)
    :param alpha_lo: relates to the bending of the dispersion relation
    towards the Brillouin zone boundary for longitudinal mode (m²/s)
    :param lattice: Lattice spacing (A)
    :param T: Temperature (K)
    """
    # Wave factor at 1st Brillouin Zone Boundary
    k_BZ = 2 * np.pi / lattice

    h_bar_m = units('1 hbar').to('J s').magnitude
    k_BZ_m = k_BZ.to('1/m').magnitude
    c_s_m = c_s.to('m/s').magnitude
    alpha_m = alpha.to('m^2/s').magnitude
    kT_m = (1 * units.k * T).to('J').magnitude

    # Calculate average net loss per acoustic scattering event
    # Isotropic Dispersion Relation, Verduin (Eq. 3.112)
    def h_bar_w_AC(k):
        return h_bar_m * (c_s_m * k - alpha_m * k**2)  # Verduin Eq. 3.114

    # Bose-Einstein distribution, Verduin (Eq. 3.117)
    def N_BE(k):
        return 1. / np.expm1(h_bar_w_AC(k) / kT_m)

    # (Verduin Eq. 3.116)
    def nominator(k):
        return h_bar_w_AC(k) * k**2

    def denominator(k):
        return (2 * N_BE(k) + 1) * k**2

    # TO DO: strip the units https://pint.readthedocs.io/en/0.7.2/wrapping.html

    y1, err1 = quad(nominator, 0, k_BZ_m)
    y2, err2 = quad(denominator, 0, k_BZ_m)
    # TO DO: assign the units back

    return ((y1 / y2) * units('J')).to('eV')
Exemple #3
0
def test_outer_shell_energies():
    """Tests that the outer shell energies have the correct units."""
    settings = read_input('data/materials/pmma.yaml')
    if not check_settings(settings, cstool_model):
        raise ValueError("Parsed settings do not conform the model.")

    fn = outer_shell_energies(settings)
    K = np.logspace(1, 4, 100) * units.eV
    osi = fn(K)

    assert osi.shape == (100, )
    assert osi.dimensionality == units('eV').dimensionality
Exemple #4
0
def test_phonon_cs_fn_dual():
    """Tests that the phonon subroutine returns a function that
    can handle arrays and returns correct units."""
    settings = read_input('data/materials/pmma.yaml')
    if not check_settings(settings, cstool_model):
        raise ValueError("Parsed settings do not conform the model.")

    fn = phonon_cs_fn(settings)
    W = np.logspace(-2, 3, 100) * units.eV
    theta = np.linspace(0, np.pi, 100) * units.rad
    cs = fn(theta, W[:, None])

    assert cs.shape == (100, 100)
    assert cs.dimensionality == units('m²/sr').dimensionality
Exemple #5
0
def test_inelastic_cs_fn():
    """Tests that the inelastic subroutine returns a function that
    can handle arrays and returns correct units."""
    settings = read_input('data/materials/pmma.yaml')
    if not check_settings(settings, cstool_model):
        raise ValueError("Parsed settings do not conform the model.")

    fn = inelastic_cs_fn(settings)
    K = np.logspace(1, 4, 100) * units.eV
    W = np.logspace(-4, 4, 100) * units.eV
    cs = fn(K, W[:, None])
    print(cs)

    assert cs.shape == (100, 100)
    assert cs.dimensionality == units('m²/eV').dimensionality
Exemple #6
0
 def elastic_cs_fn(a, E):
     return log_interpolate(
         lambda E: phonon_cs_fn(s)(a, E).to('cm^2').magnitude,
         lambda E: mcs.unsafe(a,
                              E.to('eV').magnitude.flat), lambda x: x,
         100 * units.eV, 200 * units.eV)(E) * units('cm^2/rad')
Exemple #7
0
def compute_elastic_tcs_icdf(dcs, P):
    def integrant(theta):
        return dcs(theta) * 2 * np.pi * np.sin(theta)

    return compute_tcs_icdf(integrant, 0 * units('rad'), np.pi * units('rad'),
                            P)
Exemple #8
0
        tcs, icdf = compute_inelastic_tcs_icdf(
            dcs, p_inel, s.elf_file.get_min_energy(), w0_max,
            s.elf_file.get_min_energy_interval())
        inel_tcs[i] = tcs.to('m^2')
        inel_icdf[i] = icdf.to('eV')
        print('.', end='', flush=True)
    print()

    # ionization
    e_ion = np.logspace(0, 4, 1024) * units.eV
    p_ion = np.linspace(0.0, 1.0, 1024)

    print("# Computing ionization energy probabilities")
    shells = ionization_shells(s)

    tcstot_at_K = np.zeros(e_ion.shape) * units('m^2')
    for shell in shells:
        shell['cs_at_K'] = np.zeros(e_ion.shape) * units('m^2')
        margin = 10 * units.eV
        i_able = ((e_ion + margin) > shell['B'])
        j_able = (shell['K'] > shell['B']) & (shell['cs'] > 0 * units('m^2'))
        shell['cs_at_K'][i_able] = ion_loglog_interp(
            shell['K'][j_able], shell['cs'][j_able])(
                (e_ion + margin)[i_able]).to('m^2')
        tcstot_at_K += shell['cs_at_K']

    Pcum_at_K = np.zeros(e_ion.shape)
    for shell in shells:
        shell['P_at_K'] = np.zeros(e_ion.shape)
        i_able = (tcstot_at_K > 0 * units('m^2'))
        shell['P_at_K'][
Exemple #9
0
                generator=lambda v: v if v is None else '{:~P}'.format(v),
                parser=lambda s: s if s is None else units.parse_expression(s))


element_model = Model([
    ('count',     Type("Integer abundance", default=None,
                       check=is_integer)),
    ('Z',         Type("Atomic number", default=None,
                       check=is_integer)),
    ('M',         quantity("Molar mass", 'g/mol'))
])

phonon_branch_model = Model([
    ('alpha',     maybe_quantity(
        "Bending in dispersion relation. (TV Eq. 3.112)",
        'm²/s', default=units('0 m²/s'))),
    ('eps_ac',    quantity("Accoustic deformation potential", 'eV')),
    ('c_s',       quantity("Speed of sound", 'km/s'))])


phonon_model = Model([
    ('model',     Type(
        "Whether the model is the `single` or `dual` mode.",
        check=is_('single') | is_('dual'),
        default="single")),
    ('m_eff',     maybe_quantity(
        "Effective mass.", 'g', default=units('1 m_e'))),
    ('m_dos',     maybe_quantity(
        "Density of state mass.", 'g', default=units('1 m_e'))),
    ('lattice',   quantity("Lattice spacing", 'Å')),
    ('single',    ModelType(
Exemple #10
0
 def dataset_units(dataset):
     return np.array(dataset) * units(dataset.attrs['units'])
Exemple #11
0
                        help="Filename of material in HDF5 format.")
    parser.add_argument('--elastic', action='store_true')
    parser.add_argument('--inelastic', action='store_true')
    parser.add_argument('--ionization', action='store_true')
    parser.add_argument('--mfp',
                        action='store_true',
                        help='Plot mean-free-path instead of cross-section.')
    args = parser.parse_args()

    infile = h5.File(args.material_file, 'r')

    properties = {}

    for x in infile['properties']:
        name = x[0].decode('ASCII')
        value = float(x[1]) * units(x[2].decode('ASCII'))
        properties[name] = value

    print('properties:')
    for name, value in properties.items():
        print('{: <16} {}'.format(name, value))
    print()

    if not (args.elastic or args.inelastic or args.ionization):
        print('Not plotting anything. Use the -h flag for usage.')

    if args.mfp:
        rho = properties['density']

    def dataset_units(dataset):
        return np.array(dataset) * units(dataset.attrs['units'])