Aggiunge gruppo di sorgenti multiple rigide lungo x
Sostituisce la singola sorgente con un gruppo di N sorgenti equidistanti che si muovono insieme, sommando i contributi di flusso sul sensore.
This commit is contained in:
@@ -66,8 +66,12 @@ ARIA = {
|
||||
}
|
||||
|
||||
SORGENTE = {
|
||||
# La sorgente parte da x = x_inizio_m e si muove verso x_fine_m.
|
||||
"x_inizio_m": -1.0,
|
||||
# Distanza dal sensore, all'inizio della corsa, della sorgente del
|
||||
# gruppo più vicina al sensore (quella che lo raggiunge per prima).
|
||||
"x_inizio_m": 1.0,
|
||||
|
||||
# Distanza dal sensore, alla fine della corsa, della sorgente del
|
||||
# gruppo più lontana dal sensore (quella che lo supera per ultima).
|
||||
"x_fine_m": 5.0,
|
||||
|
||||
# Coordinata laterale fissa della proiezione del sensore sul lato caldo.
|
||||
@@ -81,11 +85,18 @@ SORGENTE = {
|
||||
# Velocità della sorgente lungo x.
|
||||
"velocita_m_s": 2.0,
|
||||
|
||||
# Numero di sorgenti equidistanti che si muovono insieme come un gruppo
|
||||
# rigido (stessa velocità, sigma, flusso ed efficienza).
|
||||
"numero_sorgenti": 3,
|
||||
|
||||
# Distanza lungo x tra sorgenti consecutive del gruppo.
|
||||
"distanza_sorgenti_m": 0.5,
|
||||
|
||||
# Raggio del punto gaussiano. Valore più alto = impronta termica più larga.
|
||||
"sigma_punto_m": 0.012,
|
||||
|
||||
# Flusso termico incidente massimo prima della correzione per efficienza.
|
||||
"flusso_termico_picco_W_m2": 16500000.0,
|
||||
"flusso_termico_picco_W_m2": 5500000.0,
|
||||
|
||||
# Frazione del flusso incidente che diventa effettivamente calore nella piastra.
|
||||
"efficienza_riscaldamento": 0.35,
|
||||
|
||||
+63
-21
@@ -27,46 +27,86 @@ def calcola_skin_depth_m(materiale: dict, frequenza_hz: float) -> float:
|
||||
return math.sqrt(2.0 * rho_e / (omega * mu))
|
||||
|
||||
|
||||
def _spread_sorgenti_m(sorgente: dict) -> float:
|
||||
# Distanza lungo x tra la prima e l'ultima sorgente del gruppo.
|
||||
numero_sorgenti = sorgente.get("numero_sorgenti", 1)
|
||||
distanza = sorgente.get("distanza_sorgenti_m", 0.0)
|
||||
return (numero_sorgenti - 1) * distanza
|
||||
|
||||
|
||||
def _x_riferimento_iniziale_m(sorgente: dict) -> float:
|
||||
# Posizione a t=0 della sorgente di indice 0 (quella più arretrata nel
|
||||
# verso di marcia). x_inizio_m è la distanza dal sensore della sorgente
|
||||
# più avanzata (che quindi lo raggiunge per prima).
|
||||
spread = _spread_sorgenti_m(sorgente)
|
||||
x_sensore = sorgente["x_sensore_m"]
|
||||
x_inizio = sorgente["x_inizio_m"]
|
||||
if sorgente["velocita_m_s"] >= 0:
|
||||
return (x_sensore - x_inizio) - spread
|
||||
return (x_sensore + x_inizio) + spread
|
||||
|
||||
|
||||
def _x_riferimento_finale_m(sorgente: dict) -> float:
|
||||
# Posizione di fine corsa della sorgente di indice 0. x_fine_m è la
|
||||
# distanza dal sensore della sorgente più arretrata (che quindi lo
|
||||
# supera per ultima).
|
||||
x_sensore = sorgente["x_sensore_m"]
|
||||
x_fine = sorgente["x_fine_m"]
|
||||
if sorgente["velocita_m_s"] >= 0:
|
||||
return x_sensore + x_fine
|
||||
return x_sensore - x_fine
|
||||
|
||||
|
||||
def x_sorgente_al_tempo(sorgente: dict, t_s: float) -> float:
|
||||
return sorgente["x_inizio_m"] + sorgente["velocita_m_s"] * t_s
|
||||
return _x_riferimento_iniziale_m(sorgente) + sorgente["velocita_m_s"] * t_s
|
||||
|
||||
|
||||
def sorgente_attiva(sorgente: dict, x_m: float) -> bool:
|
||||
if not sorgente.get("zero_dopo_fine", True):
|
||||
return True
|
||||
|
||||
inizio = sorgente["x_inizio_m"]
|
||||
fine = sorgente["x_fine_m"]
|
||||
v = sorgente["velocita_m_s"]
|
||||
|
||||
def _intervallo_attivo(inizio: float, fine: float, v: float, x_m: float) -> bool:
|
||||
if v >= 0:
|
||||
return inizio <= x_m <= fine
|
||||
return fine <= x_m <= inizio
|
||||
|
||||
|
||||
def flusso_termico_incidente_W_m2(sorgente: dict, t_s: float) -> tuple[float, float]:
|
||||
# Restituisce x_sorgente_m e flusso_termico_efficace_W_m2.
|
||||
# Restituisce x_sorgente_m (posizione della sorgente di riferimento) e
|
||||
# flusso_termico_efficace_W_m2 (somma dei contributi di tutte le sorgenti).
|
||||
#
|
||||
# Il movimento è rappresentato con un'impronta gaussiana centrata sulla
|
||||
# sorgente in moto. Il modello 1D vede solo il flusso lungo la linea
|
||||
# che passa per il sensore fisso.
|
||||
x = x_sorgente_al_tempo(sorgente, t_s)
|
||||
# Il movimento è rappresentato con un'impronta gaussiana centrata su
|
||||
# ciascuna sorgente in moto. Più sorgenti equidistanti si muovono insieme
|
||||
# come un gruppo rigido: condividono velocità, sigma e flusso di picco, e
|
||||
# sono sfalsate lungo x di un multiplo di "distanza_sorgenti_m". Il
|
||||
# modello 1D vede solo il flusso lungo la linea che passa per il sensore
|
||||
# fisso, sommando il contributo di tutte le sorgenti attive.
|
||||
x_rif_iniziale = _x_riferimento_iniziale_m(sorgente)
|
||||
x_rif_finale = _x_riferimento_finale_m(sorgente)
|
||||
x_riferimento = x_rif_iniziale + sorgente["velocita_m_s"] * t_s
|
||||
|
||||
if not sorgente_attiva(sorgente, x):
|
||||
return x, 0.0
|
||||
|
||||
dx = x - sorgente["x_sensore_m"]
|
||||
numero_sorgenti = sorgente.get("numero_sorgenti", 1)
|
||||
distanza = sorgente.get("distanza_sorgenti_m", 0.0)
|
||||
v = sorgente["velocita_m_s"]
|
||||
zero_dopo_fine = sorgente.get("zero_dopo_fine", True)
|
||||
dy = sorgente["offset_y_percorso_m"]
|
||||
sigma = sorgente["sigma_punto_m"]
|
||||
|
||||
gaussiana = math.exp(-0.5 * (dx * dx + dy * dy) / (sigma * sigma))
|
||||
q_totale = 0.0
|
||||
for i in range(numero_sorgenti):
|
||||
x_i = x_riferimento + i * distanza
|
||||
|
||||
q = (
|
||||
if zero_dopo_fine:
|
||||
inizio_i = x_rif_iniziale + i * distanza
|
||||
fine_i = x_rif_finale + i * distanza
|
||||
if not _intervallo_attivo(inizio_i, fine_i, v, x_i):
|
||||
continue
|
||||
|
||||
dx = x_i - sorgente["x_sensore_m"]
|
||||
gaussiana = math.exp(-0.5 * (dx * dx + dy * dy) / (sigma * sigma))
|
||||
q_totale += (
|
||||
sorgente["flusso_termico_picco_W_m2"]
|
||||
* sorgente["efficienza_riscaldamento"]
|
||||
* gaussiana
|
||||
)
|
||||
return x, q
|
||||
|
||||
return x_riferimento, q_totale
|
||||
|
||||
|
||||
def riscaldamento_volumetrico_W_m3(
|
||||
@@ -315,6 +355,8 @@ def simula_singolo(cfg_run: dict, output_csv: Path, rng: random.Random) -> dict:
|
||||
"x_sensore_m": sorgente["x_sensore_m"],
|
||||
"offset_y_percorso_m": sorgente["offset_y_percorso_m"],
|
||||
"velocita_m_s": sorgente["velocita_m_s"],
|
||||
"numero_sorgenti": sorgente.get("numero_sorgenti", 1),
|
||||
"distanza_sorgenti_m": sorgente.get("distanza_sorgenti_m", 0.0),
|
||||
"sigma_punto_m": sorgente["sigma_punto_m"],
|
||||
"flusso_termico_picco_W_m2": sorgente["flusso_termico_picco_W_m2"],
|
||||
"efficienza_riscaldamento": sorgente["efficienza_riscaldamento"],
|
||||
|
||||
Reference in New Issue
Block a user