Heat simulation

Hello everybody,

I am developping an inverse problem with PINNS :

from sympy import Symbol, Function, Number
from modulus.sym.eq.pde import PDE

class thermic_equation(PDE):
name = “thermic_equation”

def __init__(self,k):

    x = Symbol("x")
    y = Symbol("y")
    z = Symbol("z")
    Q = Symbol("Q")


    input_variables = {"x": x , "y": y, "z": z}
    T = Function("T")(*input_variables)


    self.equations = {}
    self.equations["ode_x1"] = (T.diff(x)).diff(x) + (T.diff(y)).diff(y) + (T.diff(z)).diff(z)
    self.equations["BCc"] = -k * (T.diff(y)) - Q

    print(self.equations["ode_x1"])
    print(self.equations["BCc"])

import numpy as np
from sympy import Symbol, Eq
import modulus.sym
from modulus.sym.hydra import instantiate_arch, ModulusConfig
from modulus.sym.solver import Solver
from modulus.sym.domain import Domain
from modulus.sym.geometry.primitives_3d import Box
from modulus.sym.domain.constraint import PointwiseBoundaryConstraint, PointwiseInteriorConstraint
from modulus.sym.domain.validator import PointwiseValidator
from modulus.sym.key import Key
from modulus.sym.node import Node
import pandas as pd
from thermic_equation import thermic_equation
from modulus.sym.domain.monitor import PointwiseMonitor
import torch
from modulus.sym.utils.io.plotter import ValidatorPlotter, InferencerPlotter
from modulus.sym.domain.inferencer import PointwiseInferencer
from modulus.sym.domain.monitor import PointwiseMonitor
from modulus.sym.domain.constraint import (
PointwiseBoundaryConstraint,
PointwiseInteriorConstraint,
)

@modulus.sym.main(config_path=“conf”, config_name=“config_inverse”)
def run(cfg: ModulusConfig) → None:
# Crée la liste des noeuds pour dérouler le graphe
k = 6.252196000e-04
sm = thermic_equation(k)

sm_net = instantiate_arch(
    input_keys=[Key("x"), Key("y"), Key("z")],
    output_keys=[Key("T")],
    cfg=cfg.arch.fully_connected,
)

sm_invert = instantiate_arch(
    input_keys=[Key("y")],
    output_keys=[Key("Q")],
    cfg=cfg.arch.fully_connected,
)

nodes = sm.make_nodes() + [sm_net.make_node(name="thermic_equation_network")] + [sm_invert.make_node(name="thermic_BC_network")]

# Crée la géométrie
geo = Box((0, 0, 0, 0), (0.9, 0.9, 0.9))
x = Symbol("x")
y = Symbol("y")
z = Symbol("z")
Q = Symbol("Q")

# Crée le domaine
domain = Domain()

BC = PointwiseBoundaryConstraint(
    nodes=nodes,
    geometry=geo,
    outvar={"T": 20},
    criteria=Eq(y, 0),
    batch_size=1024,
)
domain.add_constraint(BC, "bc")

BC2 = PointwiseBoundaryConstraint(
    nodes=nodes,
    geometry=geo,
    outvar={"BCc": 0},
    criteria=Eq(y, 0.9),
    batch_size=1024,
)
domain.add_constraint(BC2, "bc2")

# Ajoute la contrainte intérieure
interior = PointwiseInteriorConstraint(
    nodes=nodes,
    geometry=geo,
    outvar={"ode_x1": 0},
    batch_size=1024,
    bounds={x:(0,0.9), y:(0,0.9), z:(0, 0.9)},
    lambda_weighting={"ode_x1": 0.0001},
)
domain.add_constraint(interior, "interior")


# Solution SIMU
file_path = '/home/mufrein/Documents/sacha/data_with_temperatures.csv'
data = pd.read_csv(file_path)
# Transformation des variables 1D en variables 2D
x_grid = np.array(data['X'].values)[:, np.newaxis]
y_grid = np.array(data['Y'].values)[:, np.newaxis]
z_grid = np.array(data['Z'].values)[:, np.newaxis]
T_grid = np.array(data['t1'].values)[:, np.newaxis]

# Création des dictionnaires avec les nouvelles dimensions
invar_numpy = {"x": x_grid, "y": y_grid, "z": z_grid}
outvar_numpy = {"T": T_grid}

validator = PointwiseValidator(
    nodes=nodes, 
    invar=invar_numpy, 
    true_outvar=outvar_numpy, 
    batch_size=1024,
    plotter=ValidatorPlotter(),
)
domain.add_validator(validator)

monitor = PointwiseMonitor(
    invar_numpy,
    output_names=["Q"],
    metrics={"mean_Q": lambda var: torch.mean(var["Q"])},
    nodes=nodes,
)
domain.add_monitor(monitor)

# add inferencer data
invar_numpy = geo.sample_interior(
    100000,
    bounds={x: (0,0.9), y: (0,0.9), z: (0,0.9) },
)

    # add inferencer data
grid_inference = PointwiseInferencer(
    nodes=nodes,
    invar=invar_numpy,
    output_names=["T"],
    batch_size=1024,
    plotter=InferencerPlotter(),
)
domain.add_inferencer(grid_inference, "inf_data")

    # add monitors

print(outvar_numpy)


slv = Solver(cfg, domain)
slv.solve()

if name == “main”:
run()

The problem is i predict a constant temperature of 20 degrees.
I don’t understand why?

In my Loss function : i Know 8 points from a FEA simulation, 1 physic equation in the domain and 1 physic equation in the boundary.

The objective is to find the heat flux knowing one boundary condition and temperature at 8 points.

Thanks in advance,

have a nice day