# Applying Time Windows to Static simulation

Hello,
I have been trying to apply the Time Window to the car aerodynamics in a tunnel, however, I have been experiencing wrong output. I assumed maybe because of the wrong setup of the geometries or boundaries.

I was wondering if you have another example of using time windows used in Moving Time Window: Taylor Green Vortex Decay - NVIDIA Docs
lets say Aneurysm where we can see the blood flow ? that would be tremendously helpful since the Aneurysm has multiple geometries and correct setup. STL Geometry: Blood Flow in Intracranial Aneurysm - NVIDIA Docs

this is my code:

``````# read stl files to make geometry
point_path = to_absolute_path("examples/aneurysm/stl_files")
inlet_mesh = Tessellation.from_stl(
point_path + "/aneurysm_inlet.stl", airtight=False
)
outlet_mesh = Tessellation.from_stl(
point_path + "/aneurysm_outlet.stl", airtight=False
)
noslip_mesh = Tessellation.from_stl(
point_path + "/aneurysm_noslip.stl", airtight=False
)
integral_mesh = Tessellation.from_stl(
point_path + "/aneurysm_integral.stl", airtight=False
)
interior_mesh = Tessellation.from_stl(
point_path + "/aneurysm_closed.stl", airtight=True
)

# params
nu = 0.025
inlet_vel = 1.5

# time window parameters
time_window_size = 1.0
t_symbol = Symbol("t")
time_range = {t_symbol: (0, time_window_size)}
nr_time_windows = 10

# inlet velocity profile
def circular_parabola(x, y, z, center, normal, radius, max_vel):
centered_x = x - center[0]
centered_y = y - center[1]
centered_z = z - center[2]
distance = sqrt(centered_x ** 2 + centered_y ** 2 + centered_z ** 2)
parabola = max_vel * Max((1 - (distance / radius) ** 2), 0)
return normal[0] * parabola, normal[1] * parabola, normal[2] * parabola

# normalize meshes
def normalize_mesh(mesh, center, scale):
mesh = mesh.translate([-c for c in center])
mesh = mesh.scale(scale)
return mesh

# normalize invars
def normalize_invar(invar, center, scale, dims=2):
invar["x"] -= center[0]
invar["y"] -= center[1]
invar["z"] -= center[2]
invar["x"] *= scale
invar["y"] *= scale
invar["z"] *= scale
if "area" in invar.keys():
invar["area"] *= scale ** dims
return invar

# scale and normalize mesh and openfoam data
center = (-18.40381048596882, -50.285383353981196, 12.848136936899031)
scale = 0.4
inlet_mesh = normalize_mesh(inlet_mesh, center, scale)
outlet_mesh = normalize_mesh(outlet_mesh, center, scale)
noslip_mesh = normalize_mesh(noslip_mesh, center, scale)
integral_mesh = normalize_mesh(integral_mesh, center, scale)
interior_mesh = normalize_mesh(interior_mesh, center, scale)

# geom params
inlet_normal = (0.8526, -0.428, 0.299)
inlet_area = 21.1284 * (scale ** 2)
inlet_center = (-4.24298030045776, 4.082857101816247, -4.637790193399717)
outlet_normal = (0.33179, 0.43424, 0.83747)
outlet_area = 12.0773 * (scale ** 2)

# make list of nodes to unroll graph on
ns = NavierStokes(nu=nu * scale, rho=1.0, dim=3, time=True)
normal_dot_vel = NormalDotVec(["u", "v", "w"])
flow_net = FullyConnectedArch(
input_keys=[Key("x"), Key("y"), Key("z"), Key("t")],
output_keys=[Key("u"), Key("v"), Key("w"), Key("p")],
layer_size=256,
)
time_window_net = MovingTimeWindowArch(flow_net, time_window_size)

nodes = (
ns.make_nodes()
+ normal_dot_vel.make_nodes()
+[time_window_net.make_node(name="time_window_network")]
)

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

# make initial condition domain
ic_domain = Domain("initial_conditions")

# make moving window domain
window_domain = Domain("window")

# inlet
u, v, w = circular_parabola(
Symbol("x"),
Symbol("y"),
Symbol("z"),
center=inlet_center,
normal=inlet_normal,
max_vel=inlet_vel,
)

# make initial condition
ic = PointwiseInteriorConstraint(
nodes=nodes,
geometry=interior_mesh,
outvar={
"u":0,
"v": 0,
"w": 0,
"p": 0,
},
batch_size=cfg.batch_size.initial_condition,
lambda_weighting={"u": 100, "v": 100, "w": 100, "p": 100},
parameterization={t_symbol: 0},
)

# make constraint for matching previous windows initial condition
ic = PointwiseInteriorConstraint(
nodes=nodes,
geometry=interior_mesh,
outvar={"u_prev_step_diff": 0, "v_prev_step_diff": 0, "w_prev_step_diff": 0},
batch_size=cfg.batch_size.interior,
lambda_weighting={
"u_prev_step_diff": 100,
"v_prev_step_diff": 100,
"w_prev_step_diff": 100,
},
parameterization={t_symbol: 0},
)

inlet = PointwiseBoundaryConstraint(
nodes=nodes,
geometry=inlet_mesh,
outvar={"u": u, "v": v, "w": w},
parameterization=time_range,
batch_size=cfg.batch_size.inlet,
)

# outlet
outlet = PointwiseBoundaryConstraint(
nodes=nodes,
geometry=outlet_mesh,
outvar={"p": 0},
parameterization=time_range,
batch_size=cfg.batch_size.outlet,
)

# no slip
no_slip = PointwiseBoundaryConstraint(
nodes=nodes,
geometry=noslip_mesh,
outvar={"u": 0, "v": 0, "w": 0},
parameterization=time_range,
batch_size=cfg.batch_size.no_slip,
)

# interior
interior = PointwiseInteriorConstraint(
nodes=nodes,
geometry=interior_mesh,
outvar={"continuity": 0, "momentum_x": 0, "momentum_y": 0, "momentum_z": 0},
batch_size=cfg.batch_size.interior,
parameterization=time_range,
)

# Integral Continuity 1
integral_continuity1 = IntegralBoundaryConstraint(
nodes=nodes,
geometry=outlet_mesh,
outvar={"normal_dot_vel": 2.540},
batch_size=1,
parameterization=time_range,
integral_batch_size=cfg.batch_size.integral_continuity,
lambda_weighting={"normal_dot_vel": 0.1},
)

# Integral Continuity 2
integral_continuity2 = IntegralBoundaryConstraint(
nodes=nodes,
geometry=integral_mesh,
outvar={"normal_dot_vel": -2.540},
batch_size=1,
parameterization=time_range,
integral_batch_size=cfg.batch_size.integral_continuity,
lambda_weighting={"normal_dot_vel": 0.1},
)

# Find the bounds
point_path = to_absolute_path("examples/aneurysm/stl_files/aneurysm_closed.stl")
recb = mesh.Mesh.from_file(point_path)
min_bound = np.min(recb.points, axis=0)
max_bound = np.max(recb.points, axis=0)

bounds = {
"x": (min_bound[0], max_bound[0]),
"y": (min_bound[1], max_bound[1]),
"z": (min_bound[2], max_bound[2]),
}
mapping = {
"Points:0": "x",
"Points:1": "y",
"Points:2": "z",
"U:0": "u",
"U:1": "v",
"U:2": "w",
"p": "p",
}

invar_s = {
key: value for key, value in invar.items() if key in ["x", "y", "z"]
}
# TODO... lambda x, y, z: self.interior_mesh.sdf({"x": x, "y": y, "z": z}, {})["sdf"]
invar_p = {
key: value for key, value in invar.items() if key not in ["x", "y", "z"]
}
sdf = interior_mesh.sdf(invar_s, invar_p)
return np.less(sdf["sdf"], 0)

voxel_inferencer = VoxelInferencer(
bounds = [[min_bound[0], max_bound[0]], [min_bound[1], max_bound[1]], [min_bound[2], max_bound[2]]],
npoints = [128, 128, 128],
nodes=nodes,
output_names=["u", "v", "w", "p"],
export_map={"U": ["u", "v", "w"], "p": ["p"]},
batch_size=1024,
)

slv = SequentialSolver(
cfg,
[(1, ic_domain), (nr_time_windows, window_domain)],
custom_update_operation=time_window_net.move_window,
)

# start flow solver
slv.solve()
``````

if name == “main”:
run()

and the error I get is:

####################################
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, z]
requested var: [u, v, w, p]
computable var: [x, y, z, continuity]
####################################
Nodes in graph:
node: Sympy Node: continuity
evaluate: SympyToTorch
inputs:
derivatives: [u__x, v__y, w__z]
outputs: [continuity]
optimize: False
node: Sympy Node: momentum_x
evaluate: SympyToTorch
inputs: [u, v, w]
derivatives: [p__x, u__t, u__x, u__x__x, u__y, u__y__y, u__z, u__z__z]
outputs: [momentum_x]
optimize: False
node: Sympy Node: momentum_y
evaluate: SympyToTorch
inputs: [u, v, w]
derivatives: [p__y, v__t, v__x, v__x__x, v__y, v__y__y, v__z, v__z__z]
outputs: [momentum_y]
optimize: False
node: Sympy Node: momentum_z
evaluate: SympyToTorch
inputs: [u, v, w]
derivatives: [p__z, w__t, w__x, w__x__x, w__y, w__y__y, w__z, w__z__z]
outputs: [momentum_z]
optimize: False
node: Sympy Node: normal_dot_vel
evaluate: SympyToTorch
inputs: [normal_x, normal_y, normal_z, u, v, w]
derivatives:
outputs: [normal_dot_vel]
optimize: False
node: Arch Node: time_window_network
evaluate: MovingTimeWindowArch
inputs: [x, y, z, t]
derivatives:
outputs: [u, v, w, p, u_prev_step, v_prev_step, w_prev_step, p_prev_step, u_prev_step_diff, v_prev_step_diff, w_prev_step_diff, p_prev_step_diff]
optimize: True
####################################
Error executing job with overrides:
Traceback (most recent call last):
File “examples/transient_aneurysm/transient_aneurysm.py”, line 315, in run
voxel_inferencer = VoxelInferencer(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/inferencer/voxel.py”, line 81, in init
super().init(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/inferencer/vtkpointwise.py”, line 96, in init
super().init(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/inferencer/pointwise.py”, line 66, in init
self.model = Graph(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/graph.py”, line 94, in init
raise RuntimeError(“Failed Unrolling Graph”)
RuntimeError: Failed Unrolling Graph

Hi @fouzia

This error means you’re missing an input for the nodes you’re building a graph from. I’m not able to debug completely for you, but ensure you are providing the velocity and also a time parameterization to all your constraints. I believe the moving time window needs time explicitly.

Hello,