refactor(backend)!: separate algorithm and data layers
Reorganize algorithm packages by business responsibility, move orchestration into services, and keep database access behind pooled repositories. Harden analysis API validation, remove unsafe legacy simulation endpoints, and add regression and architecture boundary coverage. BREAKING CHANGE: legacy algorithm module paths and obsolete simulation endpoints are removed.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""Pipe-length-weighted demand allocation.
|
||||
|
||||
This module deliberately accepts plain topology data and performs no database
|
||||
or file access. Application services are responsible for loading topology.
|
||||
"""
|
||||
|
||||
from typing import Any, Mapping
|
||||
|
||||
|
||||
def allocate_demand_by_pipe_length(
|
||||
demand: float,
|
||||
topology_nodes: Mapping[str, Mapping[str, Any]],
|
||||
topology_links: Mapping[str, Mapping[str, Any]],
|
||||
) -> dict[str, float]:
|
||||
"""Allocate total demand to junctions by half of each incident link length."""
|
||||
|
||||
if not topology_nodes or not topology_links or demand == 0.0:
|
||||
return {}
|
||||
|
||||
total_link_length = sum(
|
||||
abs(float(link["length"])) for link in topology_links.values()
|
||||
)
|
||||
if total_link_length <= 0.0:
|
||||
return {}
|
||||
|
||||
demand_per_length = demand / total_link_length
|
||||
result: dict[str, float] = {}
|
||||
for node_id, node in topology_nodes.items():
|
||||
if node["type"] != "junction":
|
||||
continue
|
||||
incident_length = sum(
|
||||
abs(float(topology_links[link_id]["length"]))
|
||||
for link_id in node["links"]
|
||||
)
|
||||
result[node_id] = incident_length * demand_per_length * 0.5
|
||||
return result
|
||||
Reference in New Issue
Block a user