Boundary Conditions for pressure driven flows

Hi there, thank you for the attention.

I would like to train a model of a flow around a cylinder with a pressure driven flow.

However, I could not figure out how to set the boundary conditions correctly. I only have given two pressures (inlet: x Pa; outlet: 0 Pa), but no velocities or flow rates.
In openfoam, you can use functions like zeroGradient or InletOutlet to satisfy the boundary conditions. Which BC are needed in Modulus? Are there predefined functions for this setup?
And how do I create the full-slip BC on the channel walls in this case?

Many thanks in advance.

Hi @jflatter

What the best boundary condition is to use in Modulus is a bit of a tough question. Its very problem dependent and is research/experimental subject. I would suggest trying a few approaches (starting with perhaps is easiest to implement for you and what you would use in a numerical solver).

Unfortunately this process can be quite empirical, so be sure to look at our fluid flow examples for some initial guidance.

Things like zeroGradient can be imposed using the gradient terms in the outvar (they will be calculated using autodiff in the constraint so you can use them in your loss).

Similarly a full-slip boundary would be imposed by setting the wall normal gradient of the wall-parallel component to zero. This will be easy for boundaries along a given axis (e.g. for a wall on x-axis just set du/dy=0), but for off-axis walls you’ll need the boundary normal which should be able to be obtained from the geometry module. In the turbulent channel example the wall normal is used to for a wall function which may provide some guidance.

1 Like

Hi @ngeneva

thank you for your answer.

I tried implementing the full-slip BC for the channel walls. I used follwing code:

# make domain
domain = Domain()
x, y = Symbol("x"), Symbol("y")

# Diff for Full slip BC

input_variables = {"x": x, "y": y}

u = Function("u")(*input_variables)
v = Function("v")(*input_variables)

dudy = u.diff(y)
dvdy = v.diff(y)
# FULL slip (channel walls)
walls = PointwiseBoundaryConstraint(
    outvar={"dudy": 0},
domain.add_constraint(walls, "walls")

However, I get following error:

Error executing job with overrides: []
Traceback (most recent call last):
  File "", line 128, in run
    walls = PointwiseBoundaryConstraint(
  File "/software/modulus/22.09/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/constraint/", line 335, in __init__
  File "/software/modulus/22.09/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/constraint/", line 55, in __init__
    self.model = Graph(
  File "/software/modulus/22.09/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/", line 94, in __init__
    raise RuntimeError("Failed Unrolling Graph")
RuntimeError: Failed Unrolling Graph

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: 1) local_rank: 0 (pid: 3027) of binary: /software/modulus/22.09/bin/python3.8
Traceback (most recent call last):
  File "/software/modulus/22.09/bin/torchrun", line 8, in <module>
  File "/software/modulus/22.09/lib/python3.8/site-packages/torch/distributed/elastic/multiprocessing/errors/", line 346, in wrapper
    return f(*args, **kwargs)
  File "/software/modulus/22.09/lib/python3.8/site-packages/torch/distributed/", line 762, in main
  File "/software/modulus/22.09/lib/python3.8/site-packages/torch/distributed/", line 753, in run
  File "/software/modulus/22.09/lib/python3.8/site-packages/torch/distributed/launcher/", line 132, in __call__
    return launch_agent(self._config, self._entrypoint, list(args))
  File "/software/modulus/22.09/lib/python3.8/site-packages/torch/distributed/launcher/", line 246, in launch_agent
    raise ChildFailedError(

Thanks in advance.

Hi @jflatter

If you’re graph cannot unroll this means that it can’t figure out how to compute some needed output variable, in this case du/dy. Defining it in you main script does not tell the constraint what this is, this is the job of the node list. There’s two options here:

  1. Create a custom node that is added to your node list that tells modulus how to compute du/dy. Look at the Node.from_sympy() method. Several of our examples should use this.

  2. Use variable that modulus will understand. As seen in our examples that have derivatives as target variables, e.g. 1D wave, modulus uses double underscores to denote derivatives. I.e. du/dy == "u__y". Modulus will figure out how to compute the gradient for you.

1 Like

Hi @ngeneva

Thank you for your help. The full-slip boundary condition seems to work fine.

However, the pressure BCs for pressure driven flow are still not working properly, even using weighting. My idea was to use hard BC. I looked at the annular_ring and hemlmholtz example, but I am not shure how to apply my BC.

How do I specify hard BC for pressure at the inlet and outlet? Following code only seems to work for the outlet:

omega_E_p = omega_1

outvar["p"] = omega_E_p * invar["p_star"]

Do I need to define an equation to set hard BC for my geometry? As example:

Thanks in advance.