Riscrive il README per il modello 2D della fascetta
Documenta geometria e sistema di coordinate (con schema della sezione), la catena di approssimazioni fisiche (sorgenti gaussiane, skin depth, diffusione 2D, scambi sul contorno e conduzione circonferenziale, sensore realistico), il metodo numerico, i tre script, i punti chiave della configurazione, lo schema colonna per colonna dei CSV e le limitazioni del modello. Sostituisce la descrizione 1D obsoleta. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,39 +1,111 @@
|
||||
# Simulatore Termico 1D — Induttore Mobile, Sensore Fisso
|
||||
# Simulatore Termico 2D — Fascetta, Sorgenti a Induzione Mobili, Sensore IR Fisso
|
||||
|
||||
Questo progetto genera misurazioni CSV pseudo-realistiche per una piastra riscaldata da un induttore in movimento.
|
||||
Questo progetto genera misurazioni CSV pseudo-realistiche della temperatura di una
|
||||
fascetta (anello cilindrico sottile) riscaldata da un gruppo di sorgenti a induzione
|
||||
in movimento, osservata da un sensore a infrarossi fisso. Lo scopo è produrre dataset
|
||||
per l'addestramento e la validazione di modelli di stima/regressione termica.
|
||||
|
||||
## Idea fisica
|
||||
## Geometria
|
||||
|
||||
La geometria è semplificata a 1D attraverso lo spessore della piastra:
|
||||
La fascetta è un anello cilindrico definito da tre dimensioni:
|
||||
|
||||
- **diametro** (default 70 mm) — il diametro del cilindro;
|
||||
- **spessore** (default 0.12 mm) — lo spessore della parete;
|
||||
- **lunghezza** (default 100 mm) — l'estensione assiale lungo `x`.
|
||||
|
||||
Il dominio simulato è la **sezione rettangolare lunghezza × spessore**. Il sistema di
|
||||
coordinate ha l'origine `(0, 0)` nel vertice in alto a sinistra della sezione:
|
||||
|
||||
```text
|
||||
lato caldo, z = 0
|
||||
[sorgente / induttore]
|
||||
--------------------- piastra
|
||||
|
|
||||
| spessore
|
||||
|
|
||||
---------------------
|
||||
[sensore]
|
||||
lato freddo, z = L
|
||||
sorgenti (induttori), in moto verso -x
|
||||
▼ ▼ ▼
|
||||
(0,0) ─────────────────────────────────────► x
|
||||
│ ┌───────────────────────────────────┐ z = 0 lato ESTERNO
|
||||
│ │ sezione della fascetta │ (flusso termico)
|
||||
│ └───────────────────────────────────┘ z = spessore lato INTERNO
|
||||
▼ ┆
|
||||
z ┆ linea di vista
|
||||
▲
|
||||
sensore IR (fisso, x = 50 mm,
|
||||
a 10 mm dalla parete interna)
|
||||
```
|
||||
|
||||
L'induttore si muove lungo `x`, mentre il sensore è fisso. Poiché il modello è 1D, il movimento della sorgente è convertito in un flusso termico dipendente dal tempo:
|
||||
- **x** = direzione della lunghezza, da `0` a `lunghezza`. Le sorgenti viaggiano in
|
||||
direzione `-x` sul lato esterno.
|
||||
- **z** = direzione dello spessore, da `0` (lato esterno, dove arriva il flusso
|
||||
termico) a `spessore` (lato interno, osservato dal sensore).
|
||||
- **y** = coordinata circonferenziale (lungo la circonferenza π·diametro). Non è
|
||||
risolta spazialmente: vedi sotto come viene trattata.
|
||||
|
||||
```text
|
||||
q(t) è massimo quando x_sorgente(t) è allineata con x_sensore
|
||||
```
|
||||
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 superficie
|
||||
interna nel punto `x` configurato (default 50 mm, al centro della lunghezza).
|
||||
|
||||
Il calore viene depositato attraverso lo spessore con un decadimento esponenziale basato sulla skin depth.
|
||||
## Modello fisico
|
||||
|
||||
Non è una simulazione FEM elettromagnetica + termica completa: è un generatore
|
||||
pratico di dataset. La catena di approssimazioni è la seguente.
|
||||
|
||||
1. **Sorgenti gaussiane in moto** — ogni sorgente ha un'impronta gaussiana di raggio
|
||||
`sigma_punto_m`. Un gruppo di `numero_sorgenti` sorgenti equidistanti
|
||||
(`distanza_sorgenti_m`) si muove rigidamente a velocità costante. Il profilo di
|
||||
flusso sul lato esterno è la somma dei contributi:
|
||||
`q(x, t) = Σᵢ q_picco · efficienza · exp(-((x - xᵢ(t))² + Δy²) / (2σ²))`.
|
||||
L'offset circonferenziale `Δy` tra il percorso delle sorgenti e il punto osservato
|
||||
dal sensore non è risolto spazialmente: entra come attenuazione gaussiana del flusso.
|
||||
|
||||
2. **Skin depth** — il riscaldamento a induzione è approssimato come riscaldamento
|
||||
volumetrico che decade esponenzialmente con la profondità `z`:
|
||||
`q_vol(x, z) = q(x) · exp(-z/δ) / (δ·(1 - exp(-spessore/δ)))`, normalizzato in modo
|
||||
da conservare il flusso superficiale. La skin depth `δ = √(2ρₑ/(ωμ))` è calcolata
|
||||
dalla resistività elettrica e dalla permeabilità del materiale alla frequenza di
|
||||
induzione, oppure può essere imposta con `skin_depth_fissa_m`. Per la banda
|
||||
stagnata a 20 kHz risulta ≈ 0.1 mm, confrontabile con lo spessore: la parete è
|
||||
quasi isoterma attraverso lo spessore.
|
||||
|
||||
3. **Diffusione 2D del calore** — l'equazione del calore è integrata nella sezione
|
||||
`(x, z)` con volumi finiti ed Eulero implicito (incondizionatamente stabile).
|
||||
|
||||
4. **Scambi con l'esterno** — la sezione scambia calore con l'ambiente su tutto il
|
||||
contorno:
|
||||
- convezione sul lato esterno (`h_esterno_W_m2K`), sul lato interno
|
||||
(`h_interno_W_m2K`) e sui due bordi in x (`h_bordi_W_m2K`);
|
||||
- **conduzione circonferenziale**: la sezione cede calore per conduzione lungo `y`
|
||||
al resto della fascetta, assunto a temperatura ambiente. Il termine è
|
||||
`q_y = -k·(T - T_amb)/L_y²` con `L_y = lunghezza_conduzione_y_mm`, la distanza
|
||||
caratteristica su cui si sviluppa il gradiente circonferenziale (valore più
|
||||
piccolo = pozzo termico più aggressivo).
|
||||
|
||||
5. **Temperatura iniziale** — il campo parte uniformemente alla temperatura ambiente
|
||||
del run (che è randomizzata, quindi varia run per run).
|
||||
|
||||
6. **Sensore realistico** — la lettura aggiunge alla temperatura vera della superficie
|
||||
interna: inerzia del primo ordine (`costante_tempo_s`), rumore gaussiano
|
||||
(`rumore_std_C`) e quantizzazione (`quantizzazione_C`).
|
||||
|
||||
## Metodo numerico
|
||||
|
||||
- Griglia a volumi finiti `n_nodi_x × n_nodi_z` (default 100 × 15); le incognite sono
|
||||
i centri cella.
|
||||
- Eulero implicito con passo `dt_interno_s` (default 0.2 ms), più fine del periodo di
|
||||
campionamento CSV.
|
||||
- Tutti i termini (diffusione, convezione, conduzione circonferenziale) sono lineari e
|
||||
costanti nel run: la matrice sparsa viene costruita e **fattorizzata LU una sola
|
||||
volta per run** (`scipy.sparse.linalg.splu`); ogni passo temporale risolve solo i
|
||||
sistemi triangolari. Un run da 30 s simulati richiede ~20 s di calcolo.
|
||||
- Se in futuro si introducessero proprietà dipendenti dalla temperatura, la matrice
|
||||
andrebbe ricostruita e rifattorizzata a ogni passo.
|
||||
|
||||
## File
|
||||
|
||||
```text
|
||||
config.py tutti i parametri di simulazione
|
||||
materials.py proprietà dei materiali
|
||||
simulate.py genera i file CSV
|
||||
plot_csv.py utilità di visualizzazione rapida
|
||||
dataset/ file CSV generati dopo aver eseguito simulate.py
|
||||
materials.py proprietà termofisiche ed elettriche dei materiali
|
||||
simulate.py motore fisico + generazione dei CSV
|
||||
plot_csv.py grafici rapidi (temperature e flusso) del primo run
|
||||
plot_animazione.py animazione della sezione: campo T(x,z), sorgenti, sensore
|
||||
dataset/ output generato da simulate.py (ricreato a ogni esecuzione)
|
||||
```
|
||||
|
||||
## Installazione
|
||||
@@ -44,106 +116,90 @@ source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Generare i file CSV
|
||||
## Uso
|
||||
|
||||
```bash
|
||||
# genera il dataset (ATTENZIONE: cancella e ricrea la cartella dataset/)
|
||||
python simulate.py
|
||||
```
|
||||
|
||||
La cartella di output conterrà:
|
||||
|
||||
```text
|
||||
dataset/run_0001.csv
|
||||
dataset/run_0002.csv
|
||||
...
|
||||
dataset/metadata.csv
|
||||
```
|
||||
|
||||
## Visualizzare un run
|
||||
|
||||
```bash
|
||||
# grafici statici del primo run (temperatura e flusso nel tempo)
|
||||
python plot_csv.py
|
||||
|
||||
# animazione della sezione durante il passaggio delle sorgenti
|
||||
python plot_animazione.py
|
||||
```
|
||||
|
||||
## Principali punti di configurazione
|
||||
Gli script di visualizzazione aprono finestre interattive (backend Qt); se il backend
|
||||
non è interattivo (es. sessione senza display) salvano automaticamente PNG/GIF in
|
||||
`dataset/`.
|
||||
|
||||
Modifica `config.py`.
|
||||
L'animazione riproduce esattamente la fisica di `run_0001` (stesso seed) e mostra tre
|
||||
pannelli allineati: il profilo di flusso `q(x)` con le sorgenti in transito, il campo
|
||||
di temperatura nella sezione con il sensore IR, e la temperatura nel punto osservato
|
||||
(vera e con inerzia del sensore). Finestra temporale e cadenza dei fotogrammi si
|
||||
regolano con le costanti in testa a `plot_animazione.py`.
|
||||
|
||||
### Piastra
|
||||
## Configurazione
|
||||
|
||||
```python
|
||||
PIASTRA = {
|
||||
"spessore_m": 0.005,
|
||||
"n_nodi": 61,
|
||||
"temperatura_iniziale_C": 25.0,
|
||||
"materiale": "acciaio_basso_carbonio",
|
||||
}
|
||||
```
|
||||
Tutto si modifica in `config.py`. I dizionari principali:
|
||||
|
||||
### Sorgente mobile
|
||||
| Dizionario | Contenuto |
|
||||
|------------------|---------------------------------------------------------------------------|
|
||||
| `SIMULAZIONE` | numero di run, durata, campionamento CSV, passo interno, seed, cartella |
|
||||
| `FASCETTA` | diametro, lunghezza, spessore, griglia, conduzione circonferenziale, materiale |
|
||||
| `ARIA` | temperatura ambiente e coefficienti di convezione dei quattro lati |
|
||||
| `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 run |
|
||||
|
||||
```python
|
||||
SORGENTE = {
|
||||
"x_inizio_m": -0.08,
|
||||
"x_fine_m": 0.08,
|
||||
"velocita_m_s": 0.004,
|
||||
"sigma_punto_m": 0.012,
|
||||
"flusso_termico_picco_W_m2": 70000.0,
|
||||
"efficienza_riscaldamento": 0.35,
|
||||
"frequenza_hz": 20000.0,
|
||||
}
|
||||
```
|
||||
Punti da conoscere:
|
||||
|
||||
### Aria
|
||||
- **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à, densità, calore specifico, resistività elettrica, permeabilità).
|
||||
- **Randomizzazione**: ogni run perturba velocità, flusso di picco, sigma, offset y,
|
||||
temperatura ambiente e rumore del sensore con estrazioni da un RNG a seed fisso
|
||||
(`SIMULAZIONE["seed"]`): il dataset è riproducibile.
|
||||
|
||||
```python
|
||||
ARIA = {
|
||||
"temperatura_ambiente_C": 25.0,
|
||||
"h_caldo_W_m2K": 12.0,
|
||||
"h_freddo_W_m2K": 8.0,
|
||||
}
|
||||
```
|
||||
## Output
|
||||
|
||||
### Sensore
|
||||
### `dataset/run_XXXX.csv` — serie temporale del run
|
||||
|
||||
```python
|
||||
SENSORE = {
|
||||
"costante_tempo_s": 1.5,
|
||||
"rumore_std_C": 0.15,
|
||||
"quantizzazione_C": 0.25,
|
||||
}
|
||||
```
|
||||
| Colonna | Significato |
|
||||
|--------------------------------|--------------------------------------------------------------------|
|
||||
| `id_run` | identificativo del run |
|
||||
| `tempo_s` | tempo simulato |
|
||||
| `x_sorgente_m` | posizione della sorgente di riferimento del gruppo |
|
||||
| `offset_y_sorgente_m` | offset circonferenziale del percorso (costante nel run) |
|
||||
| `flusso_termico_sorgente_W_m2` | flusso efficace nel punto x del sensore |
|
||||
| `skin_depth_m` | skin depth usata (costante nel run) |
|
||||
| `T_vera_lato_sensore_C` | temperatura vera della superficie interna nel punto del sensore |
|
||||
| `T_misurata_sensore_C` | lettura del sensore (inerzia + rumore + quantizzazione) |
|
||||
| `T_lato_caldo_C` | temperatura della superficie esterna nello stesso punto x |
|
||||
| `T_ambiente_C` | temperatura ambiente del run |
|
||||
| `velocita_m_s`, `sigma_punto_m`, `flusso_picco_W_m2` | parametri randomizzati del run |
|
||||
| `materiale` | chiave del materiale |
|
||||
|
||||
## Colonne CSV
|
||||
### `dataset/metadata.csv` — una riga per run
|
||||
|
||||
Ogni `run_XXXX.csv` contiene:
|
||||
Contiene tutti i parametri effettivi del run (geometria, griglia, coefficienti di
|
||||
scambio, parametri delle sorgenti e del sensore, valori randomizzati) e le temperature
|
||||
di picco vera e misurata: utile come ground truth e per filtrare i run.
|
||||
|
||||
```text
|
||||
id_run
|
||||
tempo_s
|
||||
x_sorgente_m
|
||||
offset_y_sorgente_m
|
||||
flusso_termico_sorgente_W_m2
|
||||
skin_depth_m
|
||||
T_vera_lato_sensore_C
|
||||
T_misurata_sensore_C
|
||||
T_lato_caldo_C
|
||||
T_ambiente_C
|
||||
velocita_m_s
|
||||
sigma_punto_m
|
||||
flusso_picco_W_m2
|
||||
materiale
|
||||
```
|
||||
## Limitazioni
|
||||
|
||||
## Limitazione importante
|
||||
|
||||
Questo non è una simulazione FEM elettromagnetica + termica completa. È un generatore pratico di dataset.
|
||||
|
||||
La sorgente a induzione è approssimata da:
|
||||
|
||||
1. un'impronta termica gaussiana in movimento;
|
||||
2. un flusso termico efficace;
|
||||
3. deposizione esponenziale del calore attraverso lo spessore tramite skin depth;
|
||||
4. diffusione del calore 1D attraverso la piastra;
|
||||
5. perdite per convezione su entrambi i lati;
|
||||
6. inerzia, rumore e quantizzazione del sensore.
|
||||
1. Il campo elettromagnetico non è simulato: l'accoppiamento induttivo è ridotto a
|
||||
impronta gaussiana × efficienza × decadimento esponenziale in z.
|
||||
2. La coordinata circonferenziale y non è risolta: offset del percorso e conduzione
|
||||
verso il resto della fascetta sono modelli collassati (attenuazione gaussiana e
|
||||
scambio lineare verso T ambiente).
|
||||
3. Le proprietà dei materiali sono costanti con la temperatura; per gli acciai
|
||||
ferromagnetici la skin depth reale varia fortemente con temperatura e campo
|
||||
(punto di Curie non modellato).
|
||||
4. Irraggiamento non modellato: a ~220 °C le perdite radiative non sono del tutto
|
||||
trascurabili rispetto alla convezione.
|
||||
|
||||
Reference in New Issue
Block a user