PINN: vincolo IC hard — moltiplica output per t_norm per evitare trivial solution
La normalizzazione introdotta (x,t in [0,1]²) rendeva il minimo banale net=0 (T=T_AMB ovunque) troppo accessibile, causando il collasso del training. Soluzione: T = T_AMB + T_char * (t/T_END) * net(x_norm, t_norm). Così T(x,0) = T_AMB per costruzione (vincolo hard) e la rete deve trovare soluzioni non banali per t>0. La loss IC resta ma è sempre 0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,11 +15,13 @@ class HeatPINN(nn.Module):
|
||||
|
||||
def forward(self, xt):
|
||||
# Normalize inputs to [0,1]x[0,1] so both dimensions share the same scale
|
||||
scale = torch.tensor([config.L, config.T_END], device=xt.device, dtype=xt.dtype)
|
||||
xt_norm = xt / scale
|
||||
# Output scaled to physical range: T_AMB + (Q*L/K) * net
|
||||
# net learns dimensionless perturbation in [0,1] range
|
||||
return config.T_AMB + (config.Q_VAL * config.L / config.K) * self.net(xt_norm)
|
||||
x_norm = xt[:, 0:1] / config.L
|
||||
t_norm = xt[:, 1:2] / config.T_END
|
||||
xt_norm = torch.cat([x_norm, t_norm], dim=1)
|
||||
# Multiply by t_norm to enforce IC as hard constraint: T(x,0) = T_AMB exactly.
|
||||
# This eliminates the trivial solution (net=0) and forces non-trivial learning for t>0.
|
||||
T_char = config.Q_VAL * config.L / config.K
|
||||
return config.T_AMB + T_char * t_norm.squeeze(1) * self.net(xt_norm).squeeze(1)
|
||||
|
||||
|
||||
# Precomputed loss scales (depend only on config constants)
|
||||
|
||||
Reference in New Issue
Block a user