PINN: allinea output a results/pinn/ e centralizza parametri in config

- visualizer.py: sostituisce animations/ con results/pinn/TIMESTAMP/,
  nomi fissi (heatmap.html, animation.html, comparison.html) come FDM
- config.py: aggiunge sezioni architettura, sampling, Adam, L-BFGS, loss weights
- model.py: costruisce HeatPINN dinamicamente da HIDDEN_SIZE/N_HIDDEN_LAYERS;
  heat_pinn_loss legge pesi W_PDE/W_IC/W_BC da config
- engine.py: tutti i parametri di training letti da config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 14:14:11 +02:00
parent 4f050e80df
commit fbb0458f69
4 changed files with 62 additions and 32 deletions
+15 -7
View File
@@ -35,7 +35,10 @@ def _get_device():
return torch.device('cpu')
def prepare_data(N_f=4000, N_ic=400, N_bc=400):
def prepare_data(N_f=None, N_ic=None, N_bc=None):
if N_f is None: N_f = config.N_F
if N_ic is None: N_ic = config.N_IC
if N_bc is None: N_bc = config.N_BC
set_seed(42)
device = _get_device()
@@ -61,11 +64,16 @@ def prepare_data(N_f=4000, N_ic=400, N_bc=400):
return {'device': device, 'x_f': x_f, 't_f': t_f, 'x_ic': x_ic, 't_bc': t_bc}
def train_model(data, epochs=5000, patience=100):
def train_model(data, epochs=None, patience=None):
if epochs is None: epochs = config.EPOCHS
if patience is None: patience = config.PATIENCE
device = data['device']
model = HeatPINN().to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-3)
scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=30, min_lr=1e-6)
optimizer = optim.Adam(model.parameters(), lr=config.LR_ADAM)
scheduler = ReduceLROnPlateau(optimizer, mode='min',
factor=config.SCHED_FACTOR,
patience=config.SCHED_PATIENCE,
min_lr=config.SCHED_MIN_LR)
os.makedirs(MODELS_DIR, exist_ok=True)
best_loss = float('inf')
@@ -104,12 +112,12 @@ def train_model(data, epochs=5000, patience=100):
ckpt = torch.load(MODEL_SAVE_PATH, map_location=device)
model.load_state_dict(ckpt['state_dict'])
lbfgs = optim.LBFGS(model.parameters(), lr=0.1, max_iter=50,
lbfgs = optim.LBFGS(model.parameters(), lr=config.LR_LBFGS, max_iter=50,
history_size=50, tolerance_grad=1e-7, line_search_fn='strong_wolfe')
_last = {}
for step in range(20):
for step in range(config.LBFGS_STEPS):
def closure():
lbfgs.zero_grad()
loss, L_pde, L_ic, L_bc = heat_pinn_loss(
@@ -127,7 +135,7 @@ def train_model(data, epochs=5000, patience=100):
best_loss = _last['loss']
torch.save({'state_dict': model.state_dict()}, MODEL_SAVE_PATH)
if (step + 1) % 5 == 0:
print(f"L-BFGS step {step+1}/20 | Loss: {_last['loss']:.6f} "
print(f"L-BFGS step {step+1}/{config.LBFGS_STEPS} | Loss: {_last['loss']:.6f} "
f"| PDE: {_last['pde']:.6f} | IC: {_last['ic']:.6f} | BC: {_last['bc']:.6f}")
print("Training complete! Model saved.")