""" Free Space Path Loss (FSPL) model. Used as baseline and for LOS conditions. FSPL = 20*log10(d) + 20*log10(f) + 32.45 where d in km, f in MHz """ import math from app.propagation.base import PropagationModel, PropagationInput, PropagationOutput class FreeSpaceModel(PropagationModel): """Free Space Path Loss — theoretical minimum propagation loss.""" @property def name(self) -> str: return "Free-Space" @property def frequency_range(self) -> tuple: return (1, 100000) @property def distance_range(self) -> tuple: return (1, 1000000) # 1m to 1000km def calculate(self, input: PropagationInput) -> PropagationOutput: d_km = max(input.distance_m / 1000, 0.001) f = input.frequency_mhz L = 20 * math.log10(d_km) + 20 * math.log10(f) + 32.45 return PropagationOutput( path_loss_db=L, model_name=self.name, is_los=True, breakdown={ "distance_loss": 20 * math.log10(d_km), "frequency_loss": 20 * math.log10(f), "constant": 32.45, }, )