feat: aggiunge script campionamento sensori da soluzione FDM
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
"""
|
||||
Campionamento sensori dalla soluzione FDM.
|
||||
|
||||
Legge results/fdm/fdm_solution.csv (o lancia il solver FDM se non esiste),
|
||||
chiede le posizioni dei sensori e la frequenza di campionamento, salva
|
||||
results/fdm/measurements.csv con colonne: x, t, T.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
FDM_CSV = "results/fdm/fdm_solution.csv"
|
||||
OUT_CSV = "results/measurements.csv"
|
||||
|
||||
|
||||
def _load_or_solve():
|
||||
if os.path.exists(FDM_CSV):
|
||||
print(f"Carico soluzione FDM da {FDM_CSV} ...")
|
||||
df = pd.read_csv(FDM_CSV)
|
||||
x_vals = np.sort(df["x"].unique())
|
||||
t_vals = np.sort(df["t"].unique())
|
||||
T_matrix = df.pivot(index="x", columns="t", values="T").values
|
||||
return T_matrix, x_vals, t_vals
|
||||
else:
|
||||
print(f"{FDM_CSV} non trovato. Lancio il solver FDM ...")
|
||||
from fdm.solver import solve, save_csv
|
||||
T_matrix, x_vals, t_vals = solve()
|
||||
save_csv(T_matrix, x_vals, t_vals, FDM_CSV)
|
||||
return T_matrix, x_vals, t_vals
|
||||
|
||||
|
||||
def _ask_sensors(L: float) -> list[float]:
|
||||
print(f"\nDominio spaziale: [0, {L}] m")
|
||||
print("Inserisci le posizioni dei sensori separate da virgola (es: 0.2, 0.5, 0.8):")
|
||||
while True:
|
||||
raw = input(" x sensori [m]: ").strip()
|
||||
try:
|
||||
positions = [float(v.strip()) for v in raw.split(",") if v.strip()]
|
||||
if not positions:
|
||||
raise ValueError
|
||||
out_of_range = [p for p in positions if p < 0 or p > L]
|
||||
if out_of_range:
|
||||
print(f" Valori fuori range [0, {L}]: {out_of_range}. Riprova.")
|
||||
continue
|
||||
return positions
|
||||
except ValueError:
|
||||
print(" Input non valido. Usa numeri separati da virgola.")
|
||||
|
||||
|
||||
def _ask_freq(dt_fdm: float) -> float:
|
||||
max_freq = 1.0 / dt_fdm
|
||||
print(f"\nFrequenza massima (passo FDM): {max_freq:.2f} Hz")
|
||||
print("Inserisci la frequenza di campionamento [Hz]:")
|
||||
while True:
|
||||
raw = input(" f [Hz]: ").strip()
|
||||
try:
|
||||
f = float(raw)
|
||||
if f <= 0:
|
||||
raise ValueError
|
||||
if f > max_freq:
|
||||
print(f" Frequenza troppo alta (max {max_freq:.2f} Hz). Viene usata la frequenza massima.")
|
||||
f = max_freq
|
||||
return f
|
||||
except ValueError:
|
||||
print(" Input non valido. Inserisci un numero positivo.")
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 40)
|
||||
print(" Campionamento sensori FDM")
|
||||
print("=" * 40)
|
||||
|
||||
import config
|
||||
T_matrix, x_vals, t_vals = _load_or_solve()
|
||||
|
||||
sensor_positions = _ask_sensors(config.L)
|
||||
freq = _ask_freq(t_vals[1] - t_vals[0])
|
||||
|
||||
# Indici temporali al passo di campionamento
|
||||
dt_sample = 1.0 / freq
|
||||
t_sampled = np.arange(t_vals[0], t_vals[-1] + dt_sample * 0.5, dt_sample)
|
||||
t_indices = [int(np.argmin(np.abs(t_vals - t))) for t in t_sampled]
|
||||
t_indices = sorted(set(t_indices))
|
||||
|
||||
# Campionamento
|
||||
rows = []
|
||||
for x_s in sensor_positions:
|
||||
i_x = int(np.argmin(np.abs(x_vals - x_s)))
|
||||
x_actual = x_vals[i_x]
|
||||
for i_t in t_indices:
|
||||
rows.append({"x": x_actual, "t": t_vals[i_t], "T": T_matrix[i_x, i_t]})
|
||||
|
||||
df_out = pd.DataFrame(rows).sort_values(["x", "t"]).reset_index(drop=True)
|
||||
|
||||
os.makedirs(os.path.dirname(os.path.abspath(OUT_CSV)), exist_ok=True)
|
||||
df_out.to_csv(OUT_CSV, index=False)
|
||||
|
||||
n_sensors = len(sensor_positions)
|
||||
n_times = len(t_indices)
|
||||
print(f"\nSalvato: {OUT_CSV}")
|
||||
print(f" Sensori: {n_sensors} | Istanti: {n_times} | Righe totali: {len(df_out)}")
|
||||
print(f" Posizioni effettive: {sorted(df_out['x'].unique().tolist())}")
|
||||
print(f" Intervallo T: [{df_out['T'].min():.2f}, {df_out['T'].max():.2f}] °C")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user