r"""Solves the heat equation in 1D using a PINN. .. math:: \partial_t u - \partial_{xx} u & = f in \Omega \times (0, T) \\ \partial_x u & = g on \partial \Omega \times (0, T) \\ u & = u_0 on \Omega \times {0} where :math:`u: \partial \Omega \times (0, T) \to \mathbb{R}` is the unknown function, :math:`\Omega \subset \mathbb{R}` is the spatial domain and :math:`(0, T) \subset \mathbb{R}` is the time domain. Neumann boundary conditions are prescribed, and the initial condition is discontinuous. The equation is solved on a segment domain; weak boundary and initial conditions are used. Three training strategies are compared: standard PINNs, PINNs with energy natural gradient preconditioning and PINNs with Anagram preconditioning. """ # %% import matplotlib.pyplot as plt import torch from scimba_torch.approximation_space.nn_space import NNxtSpace from scimba_torch.domain.meshless_domain.domain_1d import Segment1D from scimba_torch.integration.monte_carlo import DomainSampler, TensorizedSampler from scimba_torch.integration.monte_carlo_parameters import UniformParametricSampler from scimba_torch.integration.monte_carlo_time import UniformTimeSampler from scimba_torch.neural_nets.coordinates_based_nets.mlp import GenericMLP from scimba_torch.numerical_solvers.temporal_pde.pinns import ( NaturalGradientTemporalPinns, TemporalPinns, ) from scimba_torch.physical_models.temporal_pde.heat_equation import ( HeatEquation1DStrongForm, ) from scimba_torch.plots.plots_nd import plot_abstract_approx_spaces from scimba_torch.utils.scimba_tensors import LabelTensor # %% def f_ini(x, mu): t = LabelTensor(torch.zeros_like(x.x)) return exact(t, x, mu, nb_modes=1000) def exact(t, x, mu, nb_modes=1000): x1 = x.get_components() t1 = t.get_components() + 1e-3 u_J = 5 / 4 jpi = torch.pi * torch.arange(1, nb_modes + 1)[:, None, None] c_j = 2 * (torch.sin(5 * jpi / 8) - torch.sin(3 * jpi / 8)) / jpi u_J += torch.sum( c_j * torch.exp(-(jpi**2) * t1[None, ...]) * torch.cos(jpi * x1[None, ...]), axis=0, ) return u_J domain_x = Segment1D((0, 1), is_main_domain=True) t_min, t_max = 0.0, 1e-2 sampler = TensorizedSampler( [ UniformTimeSampler((t_min, t_max)), DomainSampler(domain_x), UniformParametricSampler([(1.0, 1.0 + 1e-5)]), ] ) # %% bc_weight = 50.0 ic_weight = 500.0 # weak BC # space = NNxtSpace(1, 1, GenericMLP, domain_x, sampler, layer_sizes=[64]) pde = HeatEquation1DStrongForm(space, init=f_ini) # %% pinn = TemporalPinns( pde, bc_type="weak", ic_type="weak", optimizers="ssbfgs", bc_weight=bc_weight, ic_weight=ic_weight, ) # %% resume_solve = True if resume_solve or not pinn.load(__file__, "neumann_weak_ssbfgs"): pinn.solve( epochs=1000, n_collocation=2000, n_bc_collocation=50, n_ic_collocation=1500, ) pinn.save(__file__, "neumann_weak_ssbfgs") space2 = NNxtSpace(1, 1, GenericMLP, domain_x, sampler, layer_sizes=[32, 32, 32]) pde2 = HeatEquation1DStrongForm(space2, init=f_ini) pinn2 = NaturalGradientTemporalPinns( pde2, bc_type="weak", ic_type="weak", bc_weight=bc_weight, ic_weight=ic_weight, matrix_regularization=1e-6, ) resume_solve = True if resume_solve or not pinn2.load(__file__, "neumann_weak_ENG"): pinn2.solve( epochs=50, n_collocation=1200, n_bc_collocation=60, n_ic_collocation=1200, ) pinn2.save(__file__, "neumann_weak_ENG") space3 = NNxtSpace(1, 1, GenericMLP, domain_x, sampler, layer_sizes=[32, 32, 32]) pde3 = HeatEquation1DStrongForm(space3, init=f_ini) pinn3 = NaturalGradientTemporalPinns( pde3, bc_type="weak", ic_type="weak", bc_weight=bc_weight, ic_weight=ic_weight, ng_algo="ANaGRAM", svd_threshold=5e-2, ) resume_solve = True if resume_solve or not pinn3.load(__file__, "neumann_weak_ANaGRAM"): pinn3.solve( epochs=50, n_collocation=1200, n_bc_collocation=60, n_ic_collocation=1200, ) pinn3.save(__file__, "neumann_weak_ANaGRAM") plot_abstract_approx_spaces( (pinn.space, pinn2.space, pinn3.space), domain_x, [(1.0, 1.0 + 1e-5)], (t_min, t_max), parameters_values=([1.0], [1.0], [1.0]), time_values=[t_max], loss=(pinn.losses, pinn2.losses, pinn3.losses), residual=(pde, pde2, pde3), solution=exact, error=exact, derivatives=["ux"], # title="learning sol of 1D heat equation with TemporalPinns", ) plt.show()