Files
pinn/inverse/sample_sensors.py
T
2026-05-15 15:28:47 +02:00

113 lines
3.7 KiB
Python

"""
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()