Hi,
unfortunately, I am not able to use PointWiseMonitor, when my NN also gets the time as input. I get an error message, when initializing the PointWiseMonitor:
peak_temp_monitor = PointwiseMonitor(
geo.sample_interior(100),
output_names=["Temperat"],
metrics={"peak_temp": lambda var: torch.max(var["Temperat"])},
nodes=nodes,
requires_grad=True,
)
ic_domain.add_monitor(peak_temp_monitor)
###################################
could not unroll graph!
This is probably because you are asking to compute a value that is not an output of any node
####################################
invar: [x, y, sdf, area]
requested var: [Temperat]
computable var: [x, y, sdf, area, diffusion_Temperat]
####################################
Nodes in graph:
node: Sympy Node: diffusion_Temperat
evaluate: SympyToTorch
inputs: []
derivatives: [Temperat__t, Temperat__x__x, Temperat__y__y]
outputs: [diffusion_Temperat]
optimize: False
node: Arch Node: T_net
evaluate: FullyConnectedArch
inputs: [x, y, t]
derivatives: []
outputs: [Temperat]
optimize: True
####################################
If I remove the time dependency from and use input_keys=[Key("x"), Key("y")], instead of input_keys=[Key("x"), Key("y"), Key("t")], there is no error message:
T_net = instantiate_arch(
# input_keys=[Key("x"), Key("y"), Key("t")],
input_keys=[Key("x"), Key("y")],
output_keys=[Key("Temperat")],
cfg=cfg.arch.fully_connected,
)
Is PointWiseMonitor not applicable in case of time-dependent problems?
Below is the full code to reproduce the issue:
import torch
import numpy as np
from sympy import Symbol, Eq
import modulus.sym
from modulus.sym.hydra import instantiate_arch, ModulusConfig # to_absolute_path, ,
from modulus.sym.key import Key
from modulus.sym.solver import Solver
from modulus.sym.domain import Domain
from modulus.sym.geometry.primitives_2d import Rectangle
from modulus.sym.eq.pdes.diffusion import Diffusion
from modulus.sym.domain.constraint import (
PointwiseBoundaryConstraint,
PointwiseInteriorConstraint,
)
from modulus.sym.domain.monitor import PointwiseMonitor
from modulus.sym.domain.inferencer import PointwiseInferencer
# inferencer visualization as mesh instead of cloud
from modulus.sym.utils.io.vtk import VTKUniformGrid
from modulus.sym.domain.inferencer import PointVTKInferencer
height = 1.0
width = 1.0
heat_sink_temp = 350
base_temp = 293.498
@modulus.sym.main(config_path="conf", config_name="config")
def run(cfg: ModulusConfig) -> None:
x, y, t_symbol = Symbol("x"), Symbol("y"), Symbol("t")
time_window_size = 1.0
time_range = {t_symbol: (0, time_window_size)}
rec = Rectangle((-width / 2, -height / 2), (width / 2, height / 2))
geo = rec
diff_eq = Diffusion(T="Temperat", D=0.1, Q=0, dim=2, time=True)
T_net = instantiate_arch(
# input_keys=[Key("x"), Key("y"), Key("t")],
input_keys=[Key("x"), Key("y")],
output_keys=[Key("Temperat")],
cfg=cfg.arch.fully_connected,
)
nodes = diff_eq.make_nodes() + [T_net.make_node(name="T_net")]
ic_domain = Domain("initial_conditions")
# initial condition
IC = PointwiseInteriorConstraint(
nodes=nodes,
geometry=geo,
outvar={"Temperat": (0)},
batch_size=2500,
parameterization={t_symbol: 0.0},
)
ic_domain.add_constraint(IC, "IC")
top_wall = PointwiseBoundaryConstraint(
nodes=nodes,
geometry=rec,
outvar={"Temperat": (1.0)},
batch_size=2500,
criteria=Eq(y, height / 2),
parameterization=time_range,
)
ic_domain.add_constraint(top_wall, name="top_wall")
remaining_walls = PointwiseBoundaryConstraint(
nodes=nodes,
geometry=rec,
outvar={"Temperat": (0)},
batch_size=2500,
criteria=y < height / 2,
parameterization=time_range,
)
ic_domain.add_constraint(remaining_walls, name="walls")
peak_temp_monitor = PointwiseMonitor(
geo.sample_interior(100),
output_names=["Temperat"],
metrics={"peak_temp": lambda var: torch.max(var["Temperat"])},
nodes=nodes,
requires_grad=True,
)
ic_domain.add_monitor(peak_temp_monitor)
# add inference data for time slices
for i, specific_time in enumerate(np.linspace(0, time_window_size, 10)):
vtk_obj = VTKUniformGrid(
bounds=[[-width / 2, width / 2], [-height / 2, height / 2]],
npoints=[128, 128],
export_map={"T": ["Temperat"]},
)
grid_inference = PointVTKInferencer(
vtk_obj=vtk_obj,
nodes=nodes,
input_vtk_map={"x": "x", "y": "y"},
output_names=["Temperat"],
requires_grad=False,
invar={"t": np.full([128**2, 1], specific_time)},
batch_size=1024,
)
ic_domain.add_inferencer(grid_inference, name="time_slice_" + str(i).zfill(4))
slv = Solver(cfg, ic_domain)
slv.solve()
if __name__ == "__main__":
run()
print("finished")
I am using Docker Container modulus:24.01.