@mytec: feat: Phase 3.0 Architecture Refactor ✅
Major refactoring of RFCP backend: - Modular propagation models (8 models) - SharedMemoryManager for terrain data - ProcessPoolExecutor parallel processing - WebSocket progress streaming - Building filtering pipeline (351k → 15k) - 82 unit tests Performance: Standard preset 38s → 5s (7.6x speedup) Known issue: Detailed preset timeout (fix in 3.1.0)
This commit is contained in:
@@ -99,8 +99,12 @@ class GPUService:
|
||||
frequency_mhz: float,
|
||||
tx_height: float,
|
||||
rx_height: float = 1.5,
|
||||
environment: str = "urban",
|
||||
) -> np.ndarray:
|
||||
"""Vectorized Okumura-Hata path loss for all distances.
|
||||
"""Vectorized path loss using the appropriate propagation model.
|
||||
|
||||
Selects model based on frequency (Phase 3.0 model selection), then
|
||||
applies the correct formula in a single vectorized numpy pass.
|
||||
|
||||
Returns path loss in dB as a CPU numpy array.
|
||||
"""
|
||||
@@ -108,16 +112,47 @@ class GPUService:
|
||||
d_km = xp.maximum(d_arr / 1000.0, 0.1)
|
||||
|
||||
freq = float(frequency_mhz)
|
||||
h_tx = float(tx_height)
|
||||
h_rx = float(rx_height)
|
||||
h_tx = max(float(tx_height), 1.0)
|
||||
h_rx = max(float(rx_height), 1.0)
|
||||
|
||||
log_f = xp.log10(xp.float64(freq))
|
||||
log_hb = xp.log10(xp.float64(h_tx))
|
||||
log_hb = xp.log10(xp.float64(max(h_tx, 1.0)))
|
||||
|
||||
a_hm = (1.1 * log_f - 0.7) * h_rx - (1.56 * log_f - 0.8)
|
||||
if freq > 2000:
|
||||
# Free-Space Path Loss: FSPL = 20*log10(d_km) + 20*log10(f) + 32.45
|
||||
L = 20.0 * xp.log10(d_km) + 20.0 * log_f + 32.45
|
||||
|
||||
L = (69.55 + 26.16 * log_f - 13.82 * log_hb - a_hm
|
||||
+ (44.9 - 6.55 * log_hb) * xp.log10(d_km))
|
||||
elif freq > 1500:
|
||||
# COST-231 Hata: extends Okumura-Hata to 1500-2000 MHz
|
||||
a_hm = (1.1 * log_f - 0.7) * h_rx - (1.56 * log_f - 0.8)
|
||||
L = (46.3 + 33.9 * log_f - 13.82 * log_hb - a_hm
|
||||
+ (44.9 - 6.55 * log_hb) * xp.log10(d_km))
|
||||
if environment == "urban":
|
||||
L += 3.0 # Metropolitan center correction
|
||||
|
||||
elif freq >= 150:
|
||||
# Okumura-Hata: 150-1500 MHz
|
||||
if environment == "urban" and freq >= 400:
|
||||
a_hm = 3.2 * (xp.log10(11.75 * h_rx) ** 2) - 4.97
|
||||
else:
|
||||
a_hm = (1.1 * log_f - 0.7) * h_rx - (1.56 * log_f - 0.8)
|
||||
|
||||
L_urban = (69.55 + 26.16 * log_f - 13.82 * log_hb - a_hm
|
||||
+ (44.9 - 6.55 * log_hb) * xp.log10(d_km))
|
||||
|
||||
if environment == "suburban":
|
||||
L = L_urban - 2 * (xp.log10(freq / 28) ** 2) - 5.4
|
||||
elif environment == "rural":
|
||||
L = L_urban - 4.78 * (log_f ** 2) + 18.33 * log_f - 35.94
|
||||
elif environment == "open":
|
||||
L = L_urban - 4.78 * (log_f ** 2) + 18.33 * log_f - 40.94
|
||||
else:
|
||||
L = L_urban
|
||||
|
||||
else:
|
||||
# Very low frequency — Longley-Rice simplified (area mode)
|
||||
# Use FSPL as baseline with terrain roughness correction
|
||||
L = 20.0 * xp.log10(d_km) + 20.0 * log_f + 32.45 + 10.0
|
||||
|
||||
return _to_cpu(L)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user