davideandClaude Opus 5 1631d6c94e Rimuove il modello ai volumi finiti lasciando la sola analisi FEM
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>
2026-08-03 11:44:58 +02:00

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 0 a lunghezza.
  • theta = coordinata circonferenziale, con theta = 0 sul piano del sensore; nelle formule si usa la lunghezza d'arco s = 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).

  1. Collasso dello spessore — la temperatura è uniforme attraverso la parete. Con spessore 0.18 mm il numero di Biot h·t/k vale ~1e-7 e il tempo di diffusione attraverso la parete t²/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 con skin_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.

  2. Sorgenti gaussiane in moto — ogni sorgente ha un'impronta gaussiana isotropa nel piano (x, s) di raggio sigma_punto_m. Un gruppo di numero_sorgenti sorgenti 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'offset s₀ del percorso rispetto al piano del sensore è offset_y_percorso_m.

  3. 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 anulari x = 0 e x = lunghezza (h_bordi_W_m2K, su un'area pari a spessore × perimetro).

  4. Temperatura iniziale — il campo parte uniformemente alla temperatura ambiente dell'analisi (randomizzabile).

  5. 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.

  6. 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 strutturata n_elementi_x × n_elementi_circonferenza di 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) in prepara_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 sui n_x + 1 nodi 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). Con zero_dopo_fine ogni sorgente si spegne alla fine della propria corsa.
  • Materiale: FASCETTA["materiale"] deve essere una chiave di MATERIALI in materials.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,150,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 in materials.py sono 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).
S
Description
No description provided
Readme
258 KiB
Languages
Python 100%