CFD Online Discussion Forums

CFD Online Discussion Forums (
-   CFX (
-   -   Simulation of Axial Fan Flow using A Momentum Source Subdomain (

Liam May 30, 2011 20:23

Simulation of Axial Fan Flow using A Momentum Source Subdomain
Hello all, I have been teaching myself to use ANSYS over the past 3 months for use in my thesis and have found some of the posts on this forum to be very helpful. I am a first time poster and would really appreciate help from anyone who's had sucess with momentum sources in the past.

I have read a lot of posts on the subject of representing axial fans with momentum source subdomains, with the most helpful answers as always coming from Ghorrocks. I am having a few problems with my model and was hoping someone could help out as the documentation is fairly scant on the subject of momentum sources.

I am modelling a large axial fan whose operating point is 650m^3/s providing a static pressure rise of 135 Pa. I have access to the rest of its performance curve and have entered this as a user function named 'Fan Function' whose input is a volumetric flow rate and output is a static pressure rise. I have made a model which consists of a small cylinder representing the fan sub domain which is surrounded by a large 'enclosure' air domain.

I have then written a user expression:
"(Fan Function((massFlow()@F19.21)/(Rho))) / (0.1[m])"
This expression evaluates the user function by inputting the measured mass flow rate at face 'F19.21' which is the inlet circle face of the fan subdomain. This mass flowrate divided by 'Rho' (which is defined in another expression, Rho=1.185) gives a volumetric flowrate which is input into the 'fan function' user function to give pressure rise (based on the fan performance curve). This pressure rise is then divided by 0.1m which is the 'height' of the fan subdomain giving what I understand to be the momentum source term in the vertical (or 'y') direction.

I have set this user expression (which outputs the momentum source) as the vertical momentum source in the subdomain window (with transverse components being 0). My understanding is that this will create a model of the fan which 'reacts' to resistance downstream to settle on an operating point that the real life fan would settle on. I face the following problems.

- When the solution starts, the mass flowrate through the fan inlet face 'F19.21' is zero. This means that the expression attempts to read pressure rise at zero mass flow rate from my user function which is below the region of interpolation. I have tried to specify intitial vertical velocity components in the air domain 'initialization' tab but no value has worked. Is there a better way to setup either my user expression, user function or initial conditions so that I do not recieve this error? Bearing in mind I have no data for the fan below 300m^3/s flowrate

-In an attempt to see how the fan model would work if the user expression was working I took out the user expression and input a constant as the vertical momentum source. I found It would work for a very low value (~100) but if I change the momentum source to the expected value at operating point (~1300) I cannot get the model to solve without hitting an 'overflow' error. I have tried different 'large negative' values for the momentum source and cannot reach convergence. I have tried a lot of different mesh approaches. What exactly do the 'v' and 'vspec' refer to in the documentation when it talks about the source term being = -C(v-vspec)? How would I factor my user expression into this equation? Are there any general rules of thumb on 'stable' or 'realistic' momentum sources?

Again, any help would be greatly appreciated.

ghorrocks May 31, 2011 08:33

Q1 - If defining an initial velocity does not work then modify your expressions using an if or step function so it gives a sensible valve at zero flow. Sensible does not mean realistic, it just means something which will generate a flow and then the real equation will kick in.

Q2 - The -C(v-vspec) approach is the normal way to do this. This way you measure the pressure increase across the fan and set the flow rate accordingly, using the -C(v-vspec) equation (with vspec being the velocity for your defined flow rate). C is just a large number, and you will probably need to define a momentum source coefficient to help convergence.

Liam May 31, 2011 20:14

I have had a bit more luck using air domain vertical initialization velocities. The values I was using before were too low (~2m/s) and using higher values (~10m/s) seems to 'kick it off' a little better. I like your 'if' statement idea and I might try this as well.

I have placed a user monitor point on the inlet and outlet circular faces of the cylindrical fan momentum source. Over the solution they both converge (flatline) to values with ~80kg/s difference. at the solve point the RMS residuals have reached about 1e-5 and a conservation target imbalance allowance of max 1% has been met - so I'm pretty happy that the model has solved properly. I'm concerned with this apparent creation of mass within the momentum source. My understanding of the momentum source is that it would add a velocity source term to the NS eqn's effectively speeding up and incoming air and increasing its velocity. Doe the momentum sources actually 'add' mass the the domain they're a subdomain inside?

With regards to the "-C(v-vspec)" approach I understand that"
  • C is any large number, say I pick 100000
  • vspec is calculated from Q=VA where Q is the known fan operating point volumetric flowrate and A is the fan cross sectional area
My problem is in understanding what the 'v' term is. I have my user function that takes flowrate input and outputs a pressure - should I reverse this so that it takes a pressure input and yields a flowrate output? Would I then get the velocity from this flowrate (Q=VA) and plug this into the appropriate 'vspec' part of the momentum source input in the subdomain window?


Liam June 1, 2011 05:14

I've spent a bit more time working on the problem and was hoping someone could confirm my new way of setting the momentum source up.

I have redefined my user function to take a pressure [Pa] input and give a [m^3/s] output according to the fan performance curve.

I have interpretted the -C(v-vspec) rule as follows:

-C = 100,000
v = the program variable 'Velocity v' (y being the direction I want flow in)
vspec is calculated from the user function evaluated at the pressure difference across the fan.

The code for this (shown below) is input as the vertical momentum source term:

(-100,000)*((Velocity v)-((Fan Function((sum(Pressure)@F20.21)-(sum(Pressure)@F19.21)))/(Fan swept area)))

Where 'Fan swept area' is an expression for (PI*fanDiameter^2/4.)


Is this the best way to calculate the pressure rise across the fan using the difference between 'sum(Pressure)@fan inlet' and 'sum(Pressure)@fan outlet'? Or would an area average pressure at these faces be more suitable?

I'm having a bit of trouble getting inside the 'interpolation range' of my user function. I've tried allowing user function extrapolation but this has given strange results. If I was to setup an If statement what would be the action if the pressure difference wasn't in the range that the user function bounds? If it wasn't in the range, do I suggest a value in the range? Won't the solution then just 'hover' at this suggested value rather than solving to the real life operating point of the fan?

ghorrocks June 1, 2011 07:12

Your sum(Pressure) functions will lead to weird results. The sum function adds the value at each node in the region. This is not meaningful for what you are doing. You should use the areaAve(pressure) function to correctly calculate the pressure. Then you do not need the sum() or Fan swept area functions.

And I assume you sorted out the question from your previous post yourself.

Liam June 2, 2011 09:00

If I don't use the interpolation function and just put in the operating point values things seem to work pretty well.

I'm having some real issues getting the interpolation function to get up and running. I've tried a large range of guesses for the initial Velocity v condition and I always end up below the range. I've also tried the following IF statement which also ends up below the interpolation range, which seems impossible to me according to how the IF statement is written:

if((((areaAve(Pressure)@F20.21)-(areaAve(Pressure)@F19.21))<(40[Pa])), (((Momentum Coefficient)*((Velocity v)-((Fan Function(135.5[Pa]))/(Fan swept area))))), (((Momentum Coefficient)*((Velocity v)-((Fan Function((areaAve(Pressure)@F20.21)-(areaAve(Pressure)@F19.21)))/(Fan swept area))))))

or put more simply:

if(STATEMENT(area average pressure at fan outlet - area average pressure at fan inlet<lower interp range bound(i.e. 40Pa)), STATEMENT TRUE ACTION(user function evaluated at design operating point (i.e. 135.5 Pa ), STATEMENT FALSE ACTION(user function evaluated at average pressure difference used in condition))

This just doesn't seem to work. Is it possible to actually define the area average pressure at a certain face to be a value as an initial condition? Or, alternatively, is there a variable that counts the iterations? So I could write an IF statement that says if iteration < 2 then evaluate user function at operating point (to generate sensible flow).

Oh and as another note, I was dividing by 'Fan swept area' to get a velocity (volumetric flow rate / area = velocity) and wasn't doing this to get some sort of area average.

ghorrocks June 2, 2011 19:19

Are you using a source term coefficient? They help convergence.

Liam June 2, 2011 20:04

Yes, I have tried a few 'large' values. I think the problem lies in my function's interpolation as when I overwrite the interpolation and just give it a value it works. I'll keep trying new things until I hopefully find a way around the 'value below range' error.

philflow August 22, 2012 14:46


Did the method work in the end ? Because I'm modeling two types of fans in my analysis:

1) One fan, outside the domain as a boundary condition. If I were using Fluent, I would in the fan curve as a boundary condition.
2) Another fan as subdomain, to which I'm imposing a momentum source. It is the same fan as the one outside, so I'm using the same fan curve.

The question I'm asking is why is it that complicated to include a fan or pump in CFX ? :confused:
It's as if going to the dentist to get a tooth pulled out ! Is there an example in the tutorials I could learn from ?

Thank you very much in advance !


ghorrocks August 23, 2012 08:07

You can make the pressure of your boundary condition a function of the mass flow rate and ge the fan curve on this boundary as well, if you like. It can also be done by setting the mass flow rate from the pressure at the boundary - same thing but different way around. One approach might be more stable than the other.

There are no tutorials for this. It woudl be nice if there was, the question is asked frequently enough.

philflow August 23, 2012 09:16

3 Attachment(s)
Hello Sir,

Thank you for the quick reply. I'm running a few simple test cases in order to grasp an understanding of the methodology. I'll make the delta p as a function of the mass flow. Will this work for fans that are in the fluid domain ? I've attached a picture for you to see what I mean !

Best regards,


philflow August 23, 2012 15:11


I have defined the following variable: bctran3 as:

(-Cuser)*((Velocity w)-((fanfunction((areaAve(Pressure)@REGION:s_fan1_out )-(areaAve(Pressure)@REGION:s_fan_1_in)))/(fanarea)))

where the fanfunction is the volumetric flow ( m3/sec) as a function of the static pressure.
For the momentum source : X = 0, Y = 0 and Z = bctran3
and I'm getting very strange results. Moreover, Post doesn't recognize the fanfunction, i-e, I get an error (unrecognized name ! ) when I try to evaluate.
Strange, I get no error during the solution, but obviously something's wrong with the setup.

Has anyone came accross this type of problem ?

Thank you.


philflow August 23, 2012 15:19

2 Attachment(s)
This is the setup of the subdomain source( please see image ).
I've also shown the fan I'm working with (fan1)

Thank you very much in advance !


ghorrocks August 23, 2012 18:56

You obviously need to fix up the naming problems, and possibly generate new regions in your mesh so you can identify mesh regions.

Also, have you specified a source term coefficient? That will help a lot (See my post #7....)

philflow August 24, 2012 07:33

Hello Sir, thank you for the quick reply.

I did create mesh regions in the mesh for the air and fans.
I'm applying the source to the fans via subdomains ( one for each ), so I should be ok on that front. I need to fix the naming problem. Very strange since it accepts the name in Pre, but says that it is invalid in Post. I'll figure this one out.
Concerning the Momentum source coefficient, the user manual says that:

Source = - C * ( U - Uspec )
Source = (-C*U) + (C* Uspec)
even though the term C appears in the component of the source ( Z in my case ). I need to put in the coefficient a second time. What I don't understand is that coefficient C appears twice ( in the component field and the momentum source coefficient as well ) . Is this correct ?

Best regards,


ghorrocks August 24, 2012 07:36

No, that is not the source term coefficient. That is just the source term equation. The source term coefficient is the derivative of the source term WRT the variable controlling it (U in this case). This is used to help linearise the equations and make convergence easier.

philflow August 24, 2012 08:59

Ok, so the Momentum Source Coefficient is only there to help convergence and has nothing to do with the General Momentum Source components ?
So I'll put 100000 instead of zero.

Now, when I change my expression for the Z component of the momentum source,to:

(1)*((Velocity w)-((fanfunction((areaAve(Pressure)@REGION:s_fan1_out )-(areaAve(Pressure)@REGION:s_fan_1_in)))/(fanarea)))

where fanfunction is the fan curve given as static pressure in Pa as a function of the volume flow rate ( m3 / sec ).

Pre expects:
Expression resolves to invalid units ('m s^-1') in value set for parameter 'Momentum Source Z Component' in object '/FLOW:Flow Analysis 1

Thanks again !


ghorrocks August 25, 2012 06:31


Ok, so the Momentum Source Coefficient is only there to help convergence and has nothing to do with the General Momentum Source components ?

As for your units problem:
You set the constant C (which appears to have become 1 in your equation in post #17 - this should be a number large compared to the velocities in your simulation) to have units to evaluate to what it wants, so that would be kg.m/s. Then when you put -C in as the Momentum Source Coefficient that should have the corect units as well.

The units check is very useful as a helper to see you have these equations correct. If the units are wrong the equation is almost certainly wrong too.

philflow August 25, 2012 07:45

Hello Sir,

It's a typo from my part, I used C = 100000 actually.
Fan and pumps are hard to setup in CFX, however the whole process forces
the user to check his units, so you need to grasp the physics behind the problem you're solving !
I fixed the units problem and was able to run a test case with a momentum source based on a specific fan curve. The other problem I came across is the fact that the user functions are not transmitted to CFX-Post, so I didn't have a way to check the expression once the problem solved. On the other hand,
the user momentum source appears in the variables, so one can check if the applied value is correct or not !

I need to write a clear procedure on the setup of fans for other users ( and you could go over it, since I'm more of a stress guy than a CFD guru like you !)

Thanks again for your help in sorting out the momentum source thing for me !

Have a good weekend,


ghorrocks August 25, 2012 08:04


The other problem I came across is the fact that the user functions are not transmitted to CFX-Post
So instead you put them into a monitor point and can watch them as the simulation progresses. Of course, you could always manually calculate the pressure at the inlet and outlet and work out what mass flow that should have. Then you can check is against the actual massflow to check it correct.

Yes, this would be a good topic for an FAQ - it has been asked many times. It would be great if you wrote it up.

All times are GMT -4. The time now is 13:28.