Files
pinn/inverse/model.py
T

56 lines
1.8 KiB
Python

import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import torch
import torch.nn as nn
import config
from inverse.config_inverse import (
HIDDEN_SIZE, N_HIDDEN_LAYERS,
ALPHA_INIT, K_INIT, H_CONV_INIT,
)
class InverseHeatPINN(nn.Module):
def __init__(self, identify=('alpha', 'k', 'h_conv'), init_vals=None):
super().__init__()
layers = [nn.Linear(2, HIDDEN_SIZE), nn.Tanh()]
for _ in range(N_HIDDEN_LAYERS - 1):
layers += [nn.Linear(HIDDEN_SIZE, HIDDEN_SIZE), nn.Tanh()]
layers.append(nn.Linear(HIDDEN_SIZE, 1))
self.net = nn.Sequential(*layers)
self.identify = list(identify)
if init_vals is None:
init_vals = {}
_inits = {'alpha': ALPHA_INIT, 'k': K_INIT, 'h_conv': H_CONV_INIT}
_true = {'alpha': config.ALPHA, 'k': config.K, 'h_conv': config.H_CONV}
for name in ('alpha', 'k', 'h_conv'):
val = init_vals.get(name, _inits[name]) if name in identify else _true[name]
log_val = torch.log(torch.tensor(float(val)))
if name in identify:
setattr(self, f'log_{name}', nn.Parameter(log_val))
else:
self.register_buffer(f'log_{name}', log_val)
@property
def alpha(self):
return torch.exp(self.log_alpha)
@property
def k(self):
return torch.exp(self.log_k)
@property
def h_conv(self):
return torch.exp(self.log_h_conv)
def forward(self, xt):
x = xt[:, :1] / config.L
t = xt[:, 1:] / config.T_END
# Output scaling identica al forward PINN, ma usa i parametri appresi
T_char = config.T_AMB + (config.Q_VAL * config.L / self.k)
return config.T_AMB + (config.Q_VAL * config.L / self.k) * self.net(torch.cat([x, t], dim=1))