def test_units_3(): p = phys.light.PhotonObject(E=phys.Measurement(5, "J**1"), v=phys.Measurement([phys.light.c, 0, 0], "m**1 s**-1")) assert p.E.units == {"L": 2, "T": -2, "M": 1} assert p.v.units == {"L": 1, "T": -1} assert lin.norm(p.v) == phys.light.c
def test_units_5(): E_g = phys.Measurement(0, "J**1") + phys.Measurement(13.6, "eV**1") f = E_g / phys.light.h l = phys.light.c / f assert E_g == 1.602176634e-19 * 13.6 assert dict_equiv(E_g.units, {"L": 2, "T": -2, "M": 1}) assert f == (1.602176634e-19 * 13.6) / 6.62607015e-34 assert dict_equiv(f.units, {"T": -1}) assert l == 299792458 / ((1.602176634e-19 * 13.6) / 6.62607015e-34) assert dict_equiv(l.units, {"L": 1})
def test_units_6(): a = phys.Measurement(5, "kg**1 m**1 s**-2") l = phys.Measurement(5, "au**1") t = phys.Measurement(10, "min**2") assert a * t == 50 assert phys.Measurement(0, "kg**1 m**1") + (a * t) == (60**2) * 10 * 5 assert a * l == 25 assert (a / l).flat[0] == 5 / (5 * 149597870700) assert a**2 == 25 assert dict_equiv((a**2).units, {"M": 2, "L": 2, "S": -4}) assert np.sqrt(l) == np.sqrt(5) assert phys.Measurement(0, "m**1") + np.sqrt(l) == np.sqrt(149597870700 * 5)
def planck_phot_distribution(E_min, E_max, T, bins=1000): # Generate the bins. global last_planck_params global last_planck_gamma_norm global last_planck_cdf params = [ x.__unscaled__() if isinstance(x, physicl.Measurement) else x for x in [E_min, E_max, T, bins] ] E_min, E_max, T, bins = tuple(params) gamma_norm = [] gamma_cdf = [] E = np.linspace(E_min, E_max, bins) if last_planck_params != params: gamma = [] for x in range(len(E) - 1): gamma.append(planck_probability(E[x], E[x + 1], T)[0]) # Sum and normalize each bin tot_area = sum(gamma) gamma_norm = [x / tot_area for x in gamma] # Pick a random position along the curve. gamma_cdf = [gamma_norm[0]] for x in range(1, len(gamma_norm)): gamma_cdf.append(gamma_cdf[-1] + gamma_norm[x]) last_planck_params = params last_planck_gamma_norm = gamma_norm last_planck_cdf = gamma_cdf else: gamma_norm = last_planck_gamma_norm gamma_cdf = last_planck_cdf rand = np.random.rand() for x in range(1, len(gamma_cdf)): if gamma_cdf[x] >= rand and rand >= gamma_cdf[x - 1]: return physicl.Measurement(E[x], "J**1")
def test_units_4(): E = phys.light.E_from_wavelength(phys.Measurement(633e-9, "m**1")) assert E == (299792458 * 6.62607015e-34) / (633e-9) assert E.units == {"L": 2, "T": -2, "M": 1} wv = phys.light.wavelength_from_E(E) assert wv == 633e-9 assert dict_equiv(wv.units, {"L": 1})
def planck_distribution(E, T): E_conv = E.__unscaled__() if isinstance(E, physicl.Measurement) else E T_conv = T.__unscaled__() if isinstance(T, physicl.Measurement) else T kB_conv = kB.__unscaled__() coef1 = 15 / (np.pi**4 * kB_conv * T_conv) # J ** -1 coef2 = E_conv / (kB_conv * T_conv) # unitless coef3 = 1 / (np.e**(E_conv / (kB_conv * T_conv))) # unitless return physicl.Measurement(coef1 * (coef2**3) * coef3, "J**-1")
def generate_photons(n, fn=lambda: np.random.power(3), min=0, max=0, bins=-1): """ Generates a collection of rays according to a distribution. Works by taking n samples of fn and then using min + (max - min) * fn() to generate the photon. By default this is numpy's power distribution. """ # log N = log lambda # lambda = hc/E # log N = log (hc/E)^c # N = (hc/E)^c # fn: x is position in dist => dist count less-than-equal-to-1 # min_fn x is miniumum => min in distribution generator # max_fn analagous to min_fn out = [] for i in range(int(n)): Eo = min + (max - min) * fn() out.append( PhotonObject(E=Eo, v=physicl.Measurement([c, 0, 0], "m**1 s**-1"))) return out
import physicl import pyopencl as cl import pyopencl.array as cl_array import numpy.linalg as np_lin import numpy as np import scipy.stats as st import scipy.integrate import copy """ SI definition for speed of light """ c = physicl.Measurement( np.double(299792458), "m**1 s**-1") # Defined here: https://www.bipm.org/en/CGPM/db/17/1/ h = physicl.Measurement( np.double(6.62607015e-34), "J**1 s**1" ) # Defined here: https://www.bipm.org/utils/common/pdf/CGPM-2018/26th-CGPM-Resolutions.pdf kB = physicl.Measurement( np.double(1.380649e-23), "J**1 K**-1" ) # Boltzmann constant, defined here: https://www.bipm.org/utils/common/pdf/si-brochure/SI-Brochure-9.pdf class PhotonObject(physicl.Object): """ Represents a simple photon. Constrained to require an energy (E) and a velocity whose Euclidean norm is the speed of light. """ # Make it so we can have light that's slower than this? def __init__(self, **kwargs): """
def test_units_2(): x = phys.Measurement(1, "au**1") y = phys.Measurement(149597870700 * 1, "m**1") assert x + y == phys.Measurement(2, "au**1") assert y + x == phys.Measurement(149597870700 * 2, "m**1")
def test_units_1(): x = phys.Measurement(5, "kg**1 m**1 s**-2") y = phys.Measurement(5, "N**1") assert x == y assert x.scale == x.scale assert x.units == x.units