|
[Sponsors] |
Gas PROPERTY in function of TEMPERATURE and PRESSURE (UDF) |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
February 29, 2020, 16:20 |
Gas PROPERTY in function of TEMPERATURE and PRESSURE (UDF)
|
#1 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
I am trying to create a hypersonic flow model using ANSYS Fluent by using User Defined Functions (UDF). What I want to achieve through UDFs is to define the gas properties (density, heat capacity, thermal conductivity and viscosity) in function of the static temperature and static pressure. I have already programmed such function in "plain C", which is the programming language used in the UDFs, and the code works perfectly. I haven't used any macros at all, only the one to define the flow property (i.e. DEFINE_DENSITY). However I am facing several difficulties for compiling my functions in ANSYS Fluent and thus I would like to have support on it.
Regarding the code, temperature (t) and pressure (p) are imported and allocated in double variables. Then I perform several loops and operations in "plain C" and my final value of density (rho) is calculated at the end (also a double variable), which is the value that I want to feed into the solver again. My code looks as it is presented below: /*----------------------------------------------------------------------------------*/ #include "udf.h" #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> DEFINE_DENSITY(rho,t,p){ /*-------------------------------------------------------------------*/ /* Allocate imported variables from Fluent */ /*-------------------------------------------------------------------*/ double P = p; /* Static Pressure */ double T = t; /* Static Temperature */ /*-------------------------------------------------------------------*/ /* Set of loops in "plain C" to calculate Z (compressibility) */ /* Operations with integers and doubles */ /* Operations with arrays (i.e. Trows[i]=StartP[i+1]-StartP[i]) */ /*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/ /* Return calculated property */ /*-------------------------------------------------------------------*/ double rho; rho = 1.225*Z; return rho; } /*----------------------------------------------------------------------------------*/ My main questions are: 1) Does Fluent UDF work with "plain C"? I read the UDF manual and it states that it works in C but there are only information about MACROS and some UDF syntax don't even look like C code. 2) Which is the correct way (and variable format) to import and export variables for calculating material properties with multiple inputs? I could only find information to calculate material properties through very simple UDFs that cannot be applied for my case. I have attached the ".c" function in case someone wants to try to compile it in Fluent Thank you in advance!! |
|
February 29, 2020, 16:47 |
Code
|
#2 |
Senior Member
|
Fluent works with both, C as well as C++. You may also use FORTRAN. However, unlike C that uses one main, Fluent uses DEFINE_ macros to define functions. And these wrappers are pre-defined. There is no macro called DEFINE_DENSITY, hence, you cannot use the UDF that you have written. Since density is a property, you need to use DEFINE_PROPERTY, a macro defined for most of the properties. For a few, different wrappers are required.
The first argument of each function is the name of the function. So, just like in C, you can call the functions defined by DEFINE_ macros using their first argument as name and the rest of the arguments as the arguments of the function being called. DEFINE_PROPERTY, which you need to use, has two arguments, apart from the first one, which is a name. First argument gives the index of the cell, which is actually an integer, and the second argument gives thread ID of the cell zone, which is an integer pointer. The function automatically loops over all the cells. So, the code that you have written would be inefficient because the calculations being done will be done for each cell. If the mesh has a million cells, then this would take a lot of time. Instead of defining all the coefficients as a table within the code, it would be recommended to write those in an external file and read using a separate, general purpose code, and save in an array. And all the fields that are common for each cell should be calculated outside DEFINE_PROPERTY. Do note that Fluent has no option to call a function that is not wrapped using a DEFINE_ macro, however, a DEFINE_ macro can call any general C function defined within the code or header file. There appears to be a syntax error as well, at least one, as a missing closing parentheses. Secondly, you seem to have defined pressure as T and temperature as P. It's not an issue as such but makes the code ambiguous and error prone.
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
February 29, 2020, 17:46 |
A few comments
|
#3 |
Senior Member
|
I went through the code in little more detail. Here are a few, hopefully useful, comments
1. Inclusion of the header files, except udf.h, is not required 2. There are a lot of redundant variables in the code that can be discarded. 3. Prefer real in place of double. This maintains consistency with the precision of Fluent solver; float for single and double for double precision. Another important point is the unit system. It appears that the first column represents pressure. Though all the calculations are internal and only the compressibility factor is being calculated yet if those are in SI, then would you expect a lot of variation in density? The pressure range is lesser than 100 Pa. Secondly, do note that all the values returned by Fluent or to the Fluent within a UDF are always in SI. The last comment is about the variable names. You have names like, P, T, density, etc. These might conflict with the names defined internally within Fluent. Recommended is to use variable names that are unique in some manner, such as, some prefix or suffix that ensures that there is no conflict. Despite the scope being local, the conflict could lead to errors. May be a little off topic but the styling of the code is more like FORTRAN; the variable names, comment decorations, and intermediate variable declaration are all FORTRAN code styles. Well, a compiler wouldn't care about those.
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
March 1, 2020, 09:27 |
Answer to vinerm
|
#4 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
Thank you vinerm for your answers and your time for looking at my function, I really appreciate it. As you noticed it, I am new into C language and thus it will take me a while to get used to allocate variables in an effective way.
Regarding the code: 1) does Fluent accept "real" values? In plain C I can only work with "int", "double" and "char". Maybe I will try to move to C++ if I can work with "real" values. 2) since I am simulating hypersonic flow, the properties of each cell will experience significant changes from one to the other. Therefore I need the UDFs to calculate the gas properties according to the local cell pressure and temperature. In your opinion, how could I do this code more efficient? It will have to loop through every cell in order to uptade the gas properties for the next iteration. 3) I am aware that Fluent works in the SI. At this stage I just wanted to have a functional code that I could debugg until I meet my requirements. But thanks for telling me. I will implement the recommended changes as soon as I'm back to my office. Again, thanks for the information!! |
|
March 1, 2020, 09:56 |
Code
|
#5 |
Senior Member
|
1. real is nothing but a typedef for float and double. Fluent uses float if run in single precision and double if run in double precision. So, you can just go ahead and use real. Fluent works with that.
2. You can use your UDF, however, there are multiple options available in Fluent that could do the same, probably better, such as ideal gas law, real gas laws, NIST database, etc., that you can use do define density. 3. To make the code more efficient, you need to remove everything that has got nothing do with a cell, such as, creation of array and vectors. Even better, use only one of these. Either define your table or only the vectors that you define later. Only those statements that make use of cell pressure and temperature need to be within DEFINE_PROPERTY function. I am also not an expert, however, prefer to declare all variables in the beginning instead of at the point where those are to be used, such as, density is being declared just before its use. That's not a good practice.
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
March 1, 2020, 19:20 |
|
#6 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
in addition I can recommend you to put
Code:
#define dataRow 32 #define dataCol 8 don't use simple names like P or T for your variables, as it could be reserved fluent variable compile your code and read log
__________________
best regards ****************************** press LIKE if this message was helpful |
|
March 2, 2020, 05:53 |
Almost there
|
#7 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
I'm almost there! I have compiled the function following your tips and it worked!
However my problem now is that the solver diverges if I execute this line of code: Z = exp((log(Z_high)-log(Z_low))/(log(Phigh)-log(Plow))*(log(Pstat)-log(Plow)) + log(Z_low)); It have checked it with a case where Z should be 1 in a subsonic case (i.e. speed ~ 5m/s, T=300 K and P=101325 Pa) and thus no convergence issues should arise due to the Z value. I have try to modify the Z expresion as Z=log(5) and Z=exp(5) (just for testing) and I got finite values. Therefore the "log" and "exp" functions work in my code separately. Is there any syntax error that I am not aware of when I combine them? I have attached again my updated function, the error is right in the end. Thank you in advance! |
|
March 2, 2020, 06:11 |
Debugging
|
#8 |
Senior Member
|
The best approach would be to print all the arguments before calculating Z, i.e., use the following command before calculation of Z.
Message("ZH: %f ZL: %f PH: %f PL: %f PS: %f\n", Z_high, Z_low, Phigh, Plow, Pstat);
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
March 2, 2020, 07:31 |
Output
|
#9 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
Thank you for the tip!! I found the problem! The pressure that I am computing is negative and thus it sends a NaN when I calculate the logarithm of a negative vale. This is the console that I have:
PStat: -0.000000 TStat: 300.000000 ZH: 1.000000 ZL: 1.000000 Z: -nan(ind) PH: 0.001000 PL: 0.000100 RHO: -nan(ind) Therefore the error must be here: /*-------------------------------------------------------------------*/ /* Import Flow Conditions */ /*-------------------------------------------------------------------*/ real Pstat = C_P(c,t); /* Static Pressure in Pa */ real Tstat = C_T(c,t); /* Static Temperature in K */ Pstat = Pstat*9.86923*pow(10,-6); /* From Pa to Atm */ /*-------------------------------------------------------------------*/ Isn't "9.86923*pow(10,-6) == 9.86923*10^(-6)"? I thought that it was the correct way. |
|
March 2, 2020, 07:50 |
Exponential
|
#10 |
Senior Member
|
pow(10,-6) is indeed what you intend it to be. However, this is not a good way of writing it, since you can directly write 1e-6. Nonetheless, this would not lead to the problem. The problem most likely is coming from the precision. Are you running Fluent in double precision? In single precision, this could lead to 0.
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
March 2, 2020, 12:37 |
It works!!
|
#11 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
Finally!! It works!!
Thank you so much for you help! I have uploaded the code (Density_UDF.c ) so anyone can look at an example of calculating a flow property with an UDF. I wish I had an example like this one to follow when I started with UDFs Now I have to apply the same procedure to the other flow variables |
|
March 2, 2020, 13:00 |
Solution
|
#12 |
Senior Member
|
Along with the UDF source, could you also mention what made it work? That would be the key to make it work for others.
__________________
Regards, Vinerm PM to be used if and only if you do not want something to be shared publicly. PM is considered to be of the least priority. |
|
March 2, 2020, 13:24 |
UDFs with comments
|
#13 |
Member
Cpt. Convergence
Join Date: Feb 2020
Posts: 98
Rep Power: 8 |
I have attached the function again with some tips where I got stucked and comments for debugging, hopefully it will be useful for someone someday
The comments address UDF programming and not plain C programming, I didn't explain the loops because that would take me ages.... If someone wants to apply the same approach, this is the PDF that I am following: https://www.researchgate.net/publica...air_to_30000_K |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Setting the height of the stream in the free channel | kevinmccartin | CFX | 12 | October 13, 2022 22:43 |
Ansys CFX problem: unexpected very high temperatures in premix laminar combustion | faizan_habib7 | CFX | 4 | February 1, 2016 18:00 |
Calculation of the Governing Equations | Mihail | CFX | 7 | September 7, 2014 07:27 |
error message | cuteapathy | CFX | 14 | March 20, 2012 07:45 |
Constant velocity of the material | Sas | CFX | 15 | July 13, 2010 09:56 |