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>
61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
# Visualizzazione della sola mesh a elementi shell della fascetta, in vista
|
||
# isometrica: facce chiare con i bordi degli elementi in evidenza.
|
||
|
||
from pathlib import Path
|
||
|
||
import matplotlib
|
||
import matplotlib.pyplot as plt
|
||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||
|
||
from config import USCITA
|
||
from mesh import genera_mesh, riepilogo_mesh
|
||
|
||
|
||
def main() -> None:
|
||
dati = genera_mesh()
|
||
print(riepilogo_mesh(dati))
|
||
|
||
nodi = dati["nodi"]
|
||
facce = nodi[dati["elementi"]]
|
||
|
||
raggio_m = dati["raggio_m"]
|
||
lunghezza_m = dati["lunghezza_m"]
|
||
|
||
fig = plt.figure(figsize=(9, 7))
|
||
ax = fig.add_subplot(projection="3d")
|
||
ax.view_init(elev=35.264, azim=45)
|
||
ax.set_box_aspect((lunghezza_m, 2 * raggio_m, 2 * raggio_m))
|
||
ax.set_axis_off()
|
||
|
||
collezione = Poly3DCollection(
|
||
facce,
|
||
facecolors="#d9e3f0",
|
||
edgecolors="#2b3a55",
|
||
linewidths=0.4,
|
||
shade=True,
|
||
lightsource=matplotlib.colors.LightSource(azdeg=315, altdeg=45),
|
||
)
|
||
ax.add_collection3d(collezione)
|
||
|
||
ax.set_xlim(0.0, lunghezza_m)
|
||
ax.set_ylim(-raggio_m, raggio_m)
|
||
ax.set_zlim(-raggio_m, raggio_m)
|
||
ax.set_title(
|
||
f"Mesh shell: {dati['n_elementi_x']} × "
|
||
f"{dati['n_elementi_circonferenza']} elementi quadrangolari"
|
||
)
|
||
|
||
if matplotlib.get_backend().lower() == "agg":
|
||
cartella = Path(USCITA["cartella"])
|
||
cartella.mkdir(parents=True, exist_ok=True)
|
||
percorso = cartella / "mesh.png"
|
||
fig.savefig(percorso, dpi=150)
|
||
print(f"Backend non interattivo: immagine salvata in {percorso}")
|
||
return
|
||
|
||
plt.show()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|