Il progetto conteneva due discretizzazioni indipendenti della stessa fisica: i volumi finiti sulla sezione x-z di simulate.py (con generazione del dataset CSV e le sue animazioni 2D/3D) e gli elementi finiti sulla mesh shell di fem.py. Resta solo il secondo, che risolve la circonferenza invece di collassarla in un'attenuazione gaussiana. Eliminati simulate.py, plot_csv.py, plot_animazione.py e plot_animazione_3d.py. Il FEM dipendeva da simulate.py per la cinematica del gruppo di sorgenti e per la configurazione del run, quindi fem.py assorbe _x_riferimento_iniziale_m, _x_riferimento_finale_m, _intervallo_attivo e configurazione_randomizzata; la lettura del sensore (inerzia, rumore, quantizzazione) è ora applicata dentro simula_campo_fem e la skin depth resta calcolata dalla frequenza dell'induttore come sola grandezza diagnostica, dato che nel modello shell lo spessore è collassato. config.py perde i parametri che servivano solo ai volumi finiti (griglia n_nodi_x/n_nodi_z, campionamento e cartella del dataset, numero di processi) e guadagna FEM["durata_s"], FEM["seed"] e USCITA["cartella"]: le immagini e le animazioni vanno in output/ invece che in dataset/. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
10 KiB
Analisi Termica FEM — Fascetta, Sorgenti a Induzione Mobili, Sensore IR Fisso
Questo progetto calcola il transitorio termico di una fascetta (anello cilindrico sottile) riscaldata da un gruppo di sorgenti a induzione in movimento, osservata da un sensore a infrarossi fisso. La fascetta è discretizzata con una mesh a elementi shell quadrangolari e il campo di temperatura è risolto a elementi finiti, poi visualizzato in un'animazione 3D isometrica.
Geometria
La fascetta è un anello cilindrico definito da tre dimensioni:
- diametro (default 70 mm) — il diametro esterno del cilindro;
- spessore (default 0.18 mm) — lo spessore della parete;
- lunghezza (default 100 mm) — l'estensione assiale lungo
x.
Il dominio discretizzato è la superficie media del cilindro (raggio = (diametro − spessore)/2). Lo spessore non è discretizzato: è un attributo degli elementi shell.
sorgenti (induttori), in moto lungo x sulla superficie esterna
▼ ▼ ▼
┌───────────────────────────────────┐
x = 0 │ superficie media del cilindro │ x = lunghezza
└───────────────────────────────────┘
┆ linea di vista
▲
sensore IR (fisso, x = 50 mm, theta = 0,
a 10 mm dalla parete interna)
- x = asse del cilindro, da
0alunghezza. - theta = coordinata circonferenziale, con
theta = 0sul piano del sensore; nelle formule si usa la lunghezza d'arcos = R·theta. - Coordinate globali per la visualizzazione:
x,y = R·sin(theta),z = R·cos(theta).
Il sensore è un pirometro a infrarossi posto all'interno della fascetta, a una
distanza configurabile dalla parete interna (default 10 mm). Essendo senza contatto, la
distanza non influenza la misura: il sensore legge la temperatura della parete nel nodo
più vicino a x = 50 mm sul piano theta = 0.
Modello fisico
L'equazione risolta è quella del calore per unità di superficie media:
rho·cp·t ∂T/∂t = k·t ∇²T + q(x, s, t) − (h_est + h_int)·(T − T_amb)
con t = spessore della parete e ∇² il laplaciano nel piano (x, s).
-
Collasso dello spessore — la temperatura è uniforme attraverso la parete. Con spessore 0.18 mm il numero di Biot
h·t/kvale ~1e-7 e il tempo di diffusione attraverso la paretet²/alphaè di pochi millisecondi, molto più rapido del transito delle sorgenti. Di conseguenza la profondità di penetrazione del riscaldamento a induzione non entra nel modello: conta solo il flusso totale assorbito per unità di superficie. La skin depthδ = √(2ρₑ/(ωμ))è comunque calcolata dalla frequenza dell'induttore (frequenza_hz, oppure imposta conskin_depth_fissa_m) e riportata come grandezza diagnostica: per la banda stagnata a 20 kHz risulta ≈ 0.14 mm, confrontabile con lo spessore, il che conferma che la parete è quasi isoterma attraverso lo spessore. -
Sorgenti gaussiane in moto — ogni sorgente ha un'impronta gaussiana isotropa nel piano
(x, s)di raggiosigma_punto_m. Un gruppo dinumero_sorgentisorgenti equidistanti (distanza_sorgenti_m) si muove rigidamente a velocità costante:q(x, s, t) = Σᵢ q_picco · efficienza · exp(-((x - xᵢ(t))² + (s - s₀)²) / (2σ²)). La distanza circonferenziale è valutata sull'immagine più vicina, perché la superficie è chiusa. L'offsets₀del percorso rispetto al piano del sensore èoffset_y_percorso_m. -
Scambi con l'ambiente — convezione sulla faccia esterna (
h_esterno_W_m2K) e su quella interna (h_interno_W_m2K) su tutta la superficie, più convezione sui due bordi anularix = 0ex = lunghezza(h_bordi_W_m2K, su un'area pari a spessore × perimetro). -
Temperatura iniziale — il campo parte uniformemente alla temperatura ambiente dell'analisi (randomizzabile).
-
Sensore reale — la lettura aggiunge alla temperatura vera della parete nel punto osservato: inerzia del primo ordine (
costante_tempo_s), rumore gaussiano (rumore_std_C) e quantizzazione (quantizzazione_C), gli ultimi due applicati a ogni campionamento. -
Randomizzazione — con
RANDOMIZZAZIONE["abilitata"]ogni analisi perturba velocità, flusso di picco, sigma dello spot, offset y del percorso, temperatura ambiente e rumore del sensore con estrazioni gaussiane/uniformi da un RNG con seed fisso (FEM["seed"]): analisi diverse dello stesso setup differiscono come differirebbero due passaggi reali, restando riproducibili.
Irraggiamento non modellato e proprietà dei materiali costanti con la temperatura: a ~210 °C le perdite radiative non sono del tutto trascurabili rispetto alla convezione, e per gli acciai ferromagnetici la skin depth reale varia fortemente con temperatura e campo (punto di Curie non modellato).
Metodo numerico
- Mesh (
mesh.py): griglia strutturatan_elementi_x × n_elementi_circonferenzadi quadrilateri a 4 nodi (default 40 × 48), chiusa lungo la circonferenza senza nodi duplicati sulla cucitura. - Elementi: shell bilineari a 4 nodi. Tutti gli elementi sono rettangoli identici
dx × ds, quindi le matrici di elemento (massa e rigidezza) sono calcolate una volta sola e assemblate in forma vettorizzata. La matrice di massa di superficie è riusata per capacità termica, convezione sulle facce e carico della sorgente; la convezione sui bordi anulari usa una matrice di massa 1D sull'anello di nodi. - Integrazione temporale: Eulero implicito con passo
FEM["dt_s"](default 1 ms). Tutti i termini sono lineari e costanti, quindi la matrice di sistema è assemblata e fattorizzata LU una sola volta (scipy.sparse.linalg.splu) inprepara_stato_fem; ogni passo assembla solo il termine noto e risolve i sistemi triangolari. - Flusso nodale: l'impronta gaussiana isotropa è separabile,
q(x, s) = q_x(x) · q_s(s), e il fattore circonferenziale è costante nel tempo (precalcolato). A ogni passo si valuta quindi solo il fattore assiale suin_x + 1nodi distinti in x, espanso con un prodotto esterno. - Se in futuro si introducessero proprietà dipendenti dalla temperatura, la matrice andrebbe ricostruita e rifattorizzata a ogni passo.
File
main.py punto di ingresso da riga di comando
config.py tutti i parametri (geometria, mesh, FEM, aria, sorgente, sensore)
materials.py proprietà termofisiche ed elettriche dei materiali
mesh.py generazione della mesh a elementi shell
fem.py solutore termico transitorio a elementi finiti
plot_mesh.py disegno della sola mesh
plot_animazione_fem.py animazione 3D del campo di temperatura
output/ immagini e GIF salvate quando il backend non è interattivo
Installazione
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Uso
python main.py # elenco delle azioni disponibili
python main.py mesh # disegna la sola mesh a elementi shell
python main.py fem # integra il campo FEM e lo anima in 3D
Ogni modulo resta eseguibile anche direttamente (python plot_mesh.py,
python plot_animazione_fem.py).
Gli script aprono finestre interattive (backend Qt); se il backend non è interattivo
(es. sessione senza display) salvano automaticamente PNG/GIF in output/.
L'animazione FEM mostra due pannelli: la fascetta in vista isometrica con il campo di
temperatura dipinto sugli elementi shell e i marker delle sorgenti in transito, e la
storia della temperatura nel punto osservato dal sensore (valore nodale vero e lettura
del sensore reale). Finestra temporale iniziale e cadenza dei fotogrammi si
regolano con le costanti in testa a plot_animazione_fem.py; la durata simulata è
FEM["durata_s"].
Configurazione
Tutto si modifica in config.py. I dizionari principali:
| Dizionario | Contenuto |
|---|---|
FASCETTA |
diametro, lunghezza, spessore, materiale |
MESH |
numero di elementi shell lungo x e lungo la circonferenza |
FEM |
passo temporale, durata dell'analisi transitoria, seed |
ARIA |
temperatura ambiente e coefficienti di convezione (facce e bordi) |
SORGENTE |
corsa, velocità (il segno dà il verso), gruppo di sorgenti, gaussiana, flusso, frequenza |
SENSORE |
posizione (x e distanza dalla parete), inerzia, rumore, quantizzazione |
RANDOMIZZAZIONE |
entità delle perturbazioni per analisi |
USCITA |
cartella per immagini e animazioni salvate |
Punti da conoscere:
- Corsa delle sorgenti:
x_inizio_mè la distanza dal sensore, all'inizio della corsa, della sorgente più avanzata (quella che lo raggiunge per prima);x_fine_mè la distanza dal sensore, a fine corsa, della sorgente più arretrata (quella che lo supera per ultima). Conzero_dopo_fineogni sorgente si spegne alla fine della propria corsa. - Materiale:
FASCETTA["materiale"]deve essere una chiave diMATERIALIinmaterials.py. Per aggiungere un materiale basta una nuova voce nel dizionario (conducibilità termica, densità, calore specifico, resistività elettrica, permeabilità relativa). - Proprietà di
banda_stagnata: la banda stagnata è un nastro di acciaio a basso tenore di carbonio (0,15–0,25% C) rivestito su entrambe le facce da un sottile strato di stagno elettrolitico, dello spessore di pochi micrometri — trascurabile rispetto allo spessore tipico della parete (es. 0,18 mm) e quindi ininfluente sulle proprietà termiche, elettriche e magnetiche in massa. I valori inmaterials.pysono quindi quelli dell'acciaio dolce sottostante: Banda stagnata: tutto quello che c'è da sapere (MUNDOLATAS), Bande stagnate elettrolitiche (EUROPERF), Differenza tra banda stagnata e acciaio inossidabile (Wuxi Bright Packing).