Author: James M. Rogers, SE Ohio, 02 Oct 2024, 0227
This class is currently on github at https://github.com/BuckRogers1965/BoltzmannDist
We collapse the waveform of the entire set of all Boltzmann Distributions to a single point, and use that point to extract properties out of any temp in the entire set. At O(1). And you can encode entire computations, like Area under the curve, or FWHM.
Now everything in the library is O(1) after a percent is looked up the first time. And it caches everything at the reference temp of 5000 K and uses scale invariance to scale the energy to the requested temp. If you ask for that same % again
If you need more cached points for a large integration you are doing then adjust the cache size to fit the points you need, they are saved at the end of the run and loaded next run.
import numpy as np
from scipy import constants
from scipy.optimize import fsolve
from collections import OrderedDict
import json
import os
# Speed of light in m/s
c = 299792458
class BoltzmannDistribution:
def __init__(self):
self.representative_point = 4.7849648084645400e-20 # 50% point at 5000K
self.reference_temperature = 5000
self.cache_size = 10000
self.cache = OrderedDict()
self.cache_filename = "boltzmann_cache.json"
self.load_cache()
def scale_to_temperature(self, T):
return T / self.reference_temperature
def point_energy(self, T):
return self.representative_point * self.scale_to_temperature(T)
def peak_energy(self, T):
return self.point_energy(T) / 0.2457097414250071665
def area_under_curve(self, T):
return self.point_energy(T) * T * 10e-22/50.20444590190353665093425661
def peak_frequency(self, T):
return self.point_energy(T) * 10e32 / .1627836661598892
def fwhm(self, T):
# Full Width at Half Maximum
return self.point_energy(T)/.162935865000977884
def wavelength_from_frequency(self, frequency):
return c / frequency
def frequency_from_wavelength(self, wavelength):
return c / wavelength
def energy_at_percentage(self, T, percentage):
k = constants.Boltzmann
def equation(E):
return np.exp(-E / (k * T)) - percentage
return fsolve(equation, k*T)[0]
def calculate_energy_ratio(self, percentage):
# Calculate energy at the reference temperature (5000K)
return self.energy_at_percentage(self.reference_temperature, percentage)
def get_energy_ratio(self, percentage, temperature):
# Check if percentage is in cache
if percentage in self.cache:
reference_ratio = self.cache[percentage]
# Move to end to mark as recently used
self.cache.move_to_end(percentage)
else:
reference_ratio = self.calculate_energy_ratio(percentage)
self.cache[percentage] = reference_ratio
if len(self.cache) > self.cache_size:
# Remove least recently used item
self.cache.popitem(last=False)
# Scale to requested temperature and return
return reference_ratio * self.scale_to_temperature(temperature)
def load_cache(self):
if os.path.exists(self.cache_filename):
with open(self.cache_filename, 'r') as f:
loaded_cache = json.load(f)
self.cache = OrderedDict((float(k), v) for k, v in loaded_cache.items())
def save_cache(self):
with open(self.cache_filename, 'w') as f:
json.dump({str(k): v for k, v in self.cache.items()}, f)
def __del__(self):
self.save_cache()
No comments:
Post a Comment