PyFR boundary conditions for turbomachinery

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

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

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.

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

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.

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

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

Regards, Freddie.

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,

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.

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

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

Regards, Freddie.

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

    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.

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.

1 Like

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

I believe the following branch was used:

which uses a plugin to determine the correction.

Regards, Freddie.

1 Like

Hi @fdw,

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

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

and then update it here:

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.

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

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:

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

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.

How can I introduce a 1D kernel then?

Best regards

See:

for the supported argument types for 1D kernels.

Regards, Freddie.