# Pirometro a infrarossi montato all'interno della fascetta. # # Il sensore osserva senza contatto un punto fisso della superficie interna, # individuato dalla coordinata assiale x e dalla posizione circonferenziale # theta = 0, che per convenzione è la generatrice di riferimento del modello. # # Con una shell a una temperatura per nodo la faccia interna e quella esterna # hanno la stessa temperatura: il valore osservato è la temperatura della # shell nel punto, interpolata con le funzioni di forma dell'elemento che lo # contiene. L'approssimazione regge finché la parete è termicamente sottile # rispetto al transito della sorgente (vedi numero_fourier_spessore in # simulate.py). # # Alla temperatura vera si sovrappone la catena di misura: inerzia del primo # ordine, rumore gaussiano e quantizzazione della lettura. import numpy as np import elementi_shell as el def prepara_interpolatore(mesh: dict, x_m: float, theta_rad: float) -> dict: # Individua l'elemento che contiene il punto osservato e i pesi nodali # con cui ricostruirvi la temperatura. n_x = mesh["n_elementi_x"] n_theta = mesh["n_elementi_theta"] x_limitato = min(max(x_m, 0.0), mesh["lunghezza_m"]) i = min(n_x - 1, max(0, int(x_limitato / mesh["lato_x_m"]))) xi = 2.0 * (x_limitato - mesh["x_nodi_m"][i]) / mesh["lato_x_m"] - 1.0 arco = (theta_rad * mesh["raggio_medio_m"]) % mesh["circonferenza_m"] j = int(arco / mesh["lato_arco_m"]) % n_theta eta = 2.0 * (arco - mesh["arco_nodi_m"][j]) / mesh["lato_arco_m"] - 1.0 elemento = i * n_theta + j return { "nodi": mesh["connettivita"][elemento], "pesi": el.funzioni_forma(xi, eta), "x_m": x_limitato, "theta_rad": theta_rad, } def temperatura_osservata_C(interpolatore: dict, T: np.ndarray) -> float: return float(T[interpolatore["nodi"]] @ interpolatore["pesi"]) def aggiorna_inerzia_C( T_letta_C: float, T_vera_C: float, dt_s: float, costante_tempo_s: float ) -> float: # Risposta del primo ordine del sensore. tau = max(costante_tempo_s, 1e-9) return T_letta_C + (T_vera_C - T_letta_C) * dt_s / tau def quantizza(valore: float, passo: float) -> float: if passo <= 0.0: return valore return round(valore / passo) * passo