# PyFR boundary conditions for turbomachinery

**URL:** <https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961>\
**Category:** Cases\
**Tags:** config, compressible\
**Created:** [27 October 2023 15:28 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961 "2023-10-27T15:28:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [27 October 2023 15:28 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/1 "2023-10-27T15:28:49Z")

</div>

Hello,

I’m running a simulation in pyFR but I noticed that the results are not correct due to the fact that the outlet boundary condition (char-riem-inv) is not respected.

Here is my .ini file regarding outlet

```auto
u2 = 201.97914732939512

v2 = -214.57234097906817

rho2 = 0.008134093472774547

p2 = 583.3367859280097

[soln-bcs-outlet]
type = char-riem-inv
rho = rho2
u = u2
v = v2
p = p2

```

Attached there is the outlet pressure profile  
Do you have any suggestions?

Regards

 ![Screenshot from 2023-10-27 17-29-10](https://global.discourse-cdn.com/free1/uploads/pyfr/original/1X/0d2be92f4667bb1fc9ad277cbb21e8d6febaa341.png)

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [27 October 2023 16:33 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/2 "2023-10-27T16:33:02Z")

</div>

If you want to exactly fix the pressure why are you using a characteristic Riemann invariant condition? To fix the pressure you want `sub-out-fp`. Now is this what you want? I doubt it, since hard fixing the pressure makes it difficult for things such as vortices to leave the domain.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [27 October 2023 17:14 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/3 "2023-10-27T17:14:27Z")

</div>

It is because of the point you mentioned.

I’m simulating a turbine cascade, how would you deal with it? Change to total pressure with a bigger zone after TE or any other suggestion?

Best regards

---

<div class="post-metadata">

**Author:** ![WillT](https://avatars.discourse-cdn.com/v4/letter/w/bc79bd/32.png) [@WillT](https://pyfr.discourse.group/u/WillT)\
**Post date:** [30 October 2023 09:04 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/4 "2023-10-30T09:04:50Z")

</div>

It can be quite annoying, when simulating turbomachinery, to get an exact operating point. This is because you sort of have to guess the pressure loss coefficient. You may have to iterate a little bit changing the boundary conditions in order to get the exact condition you want.

Also just to further Freddie’s point, the characteristic Riemann invariant boundary condition iterativley solves the Riemann problem based on the specified condition and the interpolated value at the boundary. This means that the condition isn’t exactly set at the outlet. (I’ve actually had the flow in a duct reserve because of this). It would actually be unphysical to fix pressure, density and velocity at the outlet. The only time physically you can set all three is a supersonic inlet.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [30 October 2023 11:02 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/5 "2023-10-30T11:02:05Z")

</div>

Thanks a lot for your answer!  
So basically it is just a matter of repeating with different p2 values that are the non target one and try to see how close you can get with it to the target values? There is basically not a possibility of knowing this a priori.

Last question, in your T106 case from the test cases of HOW, how have you chosen your outflow angle to properly set u2 and v2 from the magnitude of the outlet velocity?

Best regards

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [30 October 2023 16:56 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/6 "2023-10-30T16:56:05Z")

</div>

Yes. There is, theoretically, the technology within PyFR to enable this to be automated but this is not currently on the roadmap.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [31 October 2023 16:16 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/7 "2023-10-31T16:16:23Z")

</div>

Do you have any idea of how could it be implemented?  
How can I at runtime specify a new value for a certain group of elements?

Regards,

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [31 October 2023 17:57 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/8 "2023-10-31T17:57:50Z")

</div>

It would make use of the externs functionality in the backend along with the ability of boundary conditions to set and update variables at runtime (via `_set_external`). This would enable the BC to change the pressure every time step.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [31 October 2023 19:58 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/9 "2023-10-31T19:58:20Z")

</div>

Thank you for your advices!

One last point (hopefully) is how to directly get the time information within a mako kernel? i tried with `${t}` but it fails even if `externs='ploc, t` is in the mako template

Best regards

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [31 October 2023 20:04 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/10 "2023-10-31T20:04:28Z")

</div>

Inside the Mako kernel you just want `t` as `${t}` is for compile-time constants.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [1 November 2023 11:39 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/11 "2023-11-01T11:39:35Z")

</div>

I tried something like this to modify the char-riem-inv

```auto
    fpdtype_t p_act = (t<=0)
                    ? ${c["p"]} 
                    : ${gmo}*ur[${nvars - 1}]
                    - ${0.5*gmo}*(1/ur[0])*${pyfr.dot('ur[{i}]', i=(1, ndims + 1))};

    fpdtype_t corr = fabs(p_act - ${ptarget})/${ptarget};
    fpdtype_t pnew = (p_act < ${ptarget})
                  ? p_act + corr
                  : p_act - corr;
    
    fpdtype_t cs = sqrt(${gamma}*pnew/${c['rho']});
    fpdtype_t ratio = cs*${2.0/gmo};
    fpdtype_t s = pnew*pow(${c['rho']}, -${gamma});

... same riem-inv-bc

```

but I do not get the expected results (with ul diverges, while with ur to estimate p\_act does not but the pressure is not ptarget)

Regards.

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [1 November 2023 12:14 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/12 "2023-11-01T12:14:23Z")

</div>

This condition is not consistent as every point on the boundary will be enforcing its own pressure.

Again, if the change was as simple as the above, it would have been implemented a while ago. However, as I mentioned above it requires modifications to the boundary condition class and the use of externals (and a root finding algorithm and boundary-integration routine).

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [21 December 2023 07:35 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/13 "2023-12-21T07:35:04Z")

</div>

Hi,

just a question regarding the correction you apply at the outflow to get the correct pressure jump.  
In your papers I’ve found δpo = 0.002285 (MTU turbine paper) and δpo = - 0.00728716915 (T106 turbine paper). How did you come up with those values? Could you please explain it a little more?

Best regards

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [21 December 2023 11:10 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/14 "2023-12-21T11:10:20Z")

</div>

I believe the following branch was used:

> **[Comparing PyFR:develop...iyer-arvind:T161-PController · PyFR/PyFR](https://github.com/PyFR/PyFR/compare/develop...iyer-arvind:PyFR:T161-PController)**
>
> PyFR. Contribute to PyFR/PyFR development by creating an account on GitHub.

which uses a plugin to determine the correction.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [23 December 2023 17:22 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/15 "2023-12-23T17:22:35Z")

</div>

Hi @fdw,

sorry for bothering you again.  
Once an external is set via \_set\_external, how can it be updated in runtime?

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [23 December 2023 17:41 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/16 "2023-12-23T17:41:13Z")

</div>

You simply update the contents of the array. This can be seen in the turbulence plugin. We declare a variable here:

> <https://github.com/PyFR/PyFR/blob/e341865faa10b1cabadd1cdd8d212b1449da0809/pyfr/plugins/turbulence.py#L258>

and then update it here:

> <https://github.com/PyFR/PyFR/blob/e341865faa10b1cabadd1cdd8d212b1449da0809/pyfr/plugins/turbulence.py#L117>

Note that it only works for array types (not scalars, which go through a different code path), although a broadcasted array wih a single element will enable you to emulate scalar arguments.

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [23 December 2023 18:57 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/17 "2023-12-23T18:57:37Z")

</div>

I’ve tried to replicate something similar but fails in updating in runtime.  
My code for setting the external is:

```auto
shape = (1,1)
self.abc = self._be.matrix(shape, np.zeros(shape), tags={'align'})
self._set_external('abc', f'in broadcast-col fpdtype_t[1]', value = self.abc)

```

and then I try to update at each time step via:

```auto
intg.system._bc_inters[0].pcorr.set(np.ones((1,1))*abc)

```

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [24 December 2023 18:40 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/18 "2023-12-24T18:40:32Z")

</div>

You’ll want to check your array description. `broadcast-col` only makes sense for 2D kernels (rows and columns) and must be of size `(..,neles)`. 1D kernels have their own constraints (but a form of broadcasting is still supported).

Regards, Freddie.

---

<div class="post-metadata">

**Author:** ![Frankx9](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@Frankx9](https://pyfr.discourse.group/u/Frankx9)\
**Post date:** [24 December 2023 18:53 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/19 "2023-12-24T18:53:31Z")

</div>

How can I introduce a 1D kernel then?

Best regards

---

<div class="post-metadata">

**Author:** ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)\
**Post date:** [2 January 2024 15:59 UTC](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961/20 "2024-01-02T15:59:46Z")

</div>

See:

> <https://github.com/PyFR/PyFR/blob/c70a927a1b2386c2c3f01df8309e1e855ba3c374/pyfr/backends/base/generator.py#L159>

for the supported argument types for 1D kernels.

Regards, Freddie.

[Next page](https://pyfr.discourse.group/t/pyfr-boundary-conditions-for-turbomachinery/961.md?page=2)
