|
[Sponsors] |
UDF to define property through interpolation of data from external files |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
November 28, 2021, 06:10 |
UDF to define property through interpolation of data from external files
|
#1 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Hello everyone,
I'm having some trouble writing UDFs to define fluid transport properties. I can successfully read experimental values from an external matrix (i.e. as function of p,T) and I think I managed to define properties at each cell value through DEFINE_PROPERTY with an interpolation function. However, importing the matrix inside the DEFINE_PROPERTY function results in an eccessive cost since at each iteration the matrix is re-opened. So the idea is to write a DEFINE_ON_DEMAND to load the property matrix (putting it into memory once and for all), and then to write a DEFINE_PROPERTY to interpolate and find the correct value. I wrote the whole process in once .c file and then compiled it with the Fluent built-in compiler. As I do so, both the matrix and the property UDF seem to be correctly loaded, but as I apply the udf in the material log, Fluent crashes (stating "the f1 process could not be started"). My guess is that I'm not able to call the matrix generated in one function, into the other. I tried storing the variable (double**) globally and I'm quite sure I'm doing that wrong. I'm totally new to both C language and Fluent UDFs, so any help would be appreciated. Thank you! I attach a summary of my code .c #include "udf.h" #include <stdio.h> #include <stdlib.h> /* global variables */ double* P; /*defining array*/ double* T; /*defining array*/ double** Var_rho; /*defining matrix*/ DEFINE_ON_DEMAND(read_density){ P = malloc(NP * sizeof(double*)); T = malloc(NT * sizeof(double*)); Var_rho=malloc(NT*sizeof(double*)); for(i=0;i<NT;++i) Var_rho[i]=malloc(NP*sizeof(double)); .... code to open external files and store arrays and matrix .... } DEFINE_PROPERTY(DensityUDF, c, t){ .... code to interpolate and define property .... (here I call something like rho11 = Var_rho[n][m] where Var_rho is the one defined in the previous function) return rho; } Thanks for any reply! |
|
November 28, 2021, 21:29 |
|
#2 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
try to use this code for memory allocation
Code:
#include "udf.h" #include <stdio.h> #include <stdlib.h> /* global variables */ real* P; /*defining array*/ real* T; /*defining array*/ real** Var_rho; /*defining matrix*/ DEFINE_ON_DEMAND(read_density){ P = (real*)malloc(NP * sizeof(real)); T = (real*)malloc(NT * sizeof(real)); Var_rho= (real**)malloc(NT*sizeof(real*)); for(i=0;i<NT;++i) Var_rho[i]=(real*)malloc(NP*sizeof(real)); .... code to open external files and store arrays and matrix .... }
__________________
best regards ****************************** press LIKE if this message was helpful |
|
November 29, 2021, 04:59 |
|
#3 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Thank you Alexander for your reply!
So does C on Fluent take "real" as a variable identifier? I was told to use "double" instead. I will try this approach for memory allocation. However, my doubts on calling a function output into another UDF still remain. Do I need to return the variable (which is a matrix) in the first UDF? And in the second one can I simply use the variable (such as abc = Var_rho [1][2]) one globally defined, or am I requested to do something else? Thank you again |
|
November 29, 2021, 05:57 |
|
#4 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
real is an internal variable type for fluent which is float for single precision and double for double precision solver
as you've defined your variable as global, you can use it later in any function
__________________
best regards ****************************** press LIKE if this message was helpful |
|
December 1, 2021, 11:55 |
|
#5 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Hello Alexander,
Thank you for your response, I tried to build the UDF with your changes but the simulation it still doesn't run (Fluent crashes). I hence tried to separate the two functions and load an UDF to read the matrix and another one to define the property, but, one they're built using the built-in compiler, as I execute on demand the first one, Fluent crashes again (so my guess is that I'm still making some mistakes in reading the matrix). The code used for the first udf is the following: #include "udf.h" #include <stdio.h> #include <stdlib.h> /*Global variables*/ static int NP=250; static int NT=838; extern real* P; extern real* T; extern real** Var_rho; DEFINE_ON_DEMAND(read_density) { int i; int j; int iP; int jT; P = (real*)malloc(NP * sizeof(real)); T = (real*)malloc(NT * sizeof(real)); Var_rho= (real**)malloc(NT*sizeof(real*)); for(i=0;i<NT;++i) Var_rho[i]=(real*)malloc(NP*sizeof(real)); FILE *fileP; FILE *fileT; FILE *fileVar; if((fileT = fopen("Temperature.txt","r")) == NULL) printf("ERROR in opening DataFileP \n"); if((fileP = fopen("Pressure.txt","r")) == NULL) printf("ERROR in opening DataFileT \n"); if((fileVar = fopen("Density.txt","r")) == NULL) printf("ERROR in opening DataFileVar \n"); for (iP = 0; iP < NP; iP++) { fscanf(fileP, "%lf", &P[iP]); /*printf("P[%d] is %lf.\n", iP, P[iP]);*/ } /*printf("\n")*/ for (jT = 0; jT < NT; jT++) { fscanf(fileT, "%lf", &T[jT]); } for (i = 0; i < NP; ++i) { for (j = 0; j < NT; ++j) { if (!fscanf(fileVar, "%lf", &Var_rho[i][j])) break; /*printf("Var_rho[%d][%d] is %lf.\n", i, j, Var_rho[i][j]);*/ } /*printf("\n");*/ } fclose(fileP); fclose(fileT); fclose(fileVar); } Is there anything that I'm missing? As said, the udf is built but when it is executed on demand Fluent crashes. I have tried with and without the "extern" statement in global variables. I would really appreciate any help, and again sorry for my poor understanding of the C language. Thank you |
|
December 2, 2021, 05:01 |
|
#6 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
add
Code:
#include <malloc.h> you don't need extern as your variables are defined here but not in other file except that code seems to be correct for single core computation to use it in parallel you should modify it, I mean, in case you will add other functionality to your code. however, this code must work in parallel as well.
__________________
best regards ****************************** press LIKE if this message was helpful |
|
December 2, 2021, 05:30 |
|
#7 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Thank you Alexander for your response,
Wow, can't believe that the error is that simple. I will try it out! As for the extern variables I do need those since this is at this UDF will follow a define_property UDF that need to read the stored Var_rho. So the idea is to execute on demand this one and then compile the define property one. As for the parallelization (my simulation needs to work in parallel) I'm currently looking at the UDF manual, do I need to add a c_loop? I thought that since I'm reading a node-independent external file it would not be necessary. And the define_property should work in parallel right? Thank you for your help! |
|
December 9, 2021, 14:32 |
|
#8 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Hello again,
I tested the new UDF (had some license problems, hence the delay) and it still doesn't work. The f1 error comes again. Sometimes I also get the SIGSEGV error. I blamed the malloc function, so I tried to statically allocate the vectors/matrix since I know their sizes, such as: real P[NP], T[NT], Var[NP][NT] and it still doesn't work. I will paste the code again hoping to find some help. The code does work in a C compiler, and besides, as I put a message at the end of the script it does appear on fluent, before crashing, pointing that the UDF is actually compiled till the end. I also tried running on both single and multiple processors. #include "udf.h" #include <malloc> static int NP=250; static int NT=838; real* P; real* T; real** Var_rho; DEFINE_ON_DEMAND(read_density) { int i; int j; int iP; int jT; P = (real*)malloc(NP * sizeof(real)); T = (real*)malloc(NT * sizeof(real)); Var_rho= (real**)malloc(NT*sizeof(real*)); for(i=0;i<NT;++i) Var_rho[i]=(real*)malloc(NP*sizeof(real)); FILE *fileP; FILE *fileT; FILE *fileVar; if((fileT = fopen("Temperature.txt","r")) == NULL) printf("ERROR in opening DataFileP \n"); if((fileP = fopen("Pressure.txt","r")) == NULL) printf("ERROR in opening DataFileT \n"); if((fileVar = fopen("Density.txt","r")) == NULL) printf("ERROR in opening DataFileVar \n"); for (i = 0; i < NP; i++) { fscanf(fileP, "%lf", &P[i]); } for (j = 0; j < NT; j++) { fscanf(fileT, "%lf", &T[j]); } for (i = 0; i < NP; ++i) { for (j = 0; j < NT; ++j) { fscanf(fileVar, "%lf", &Var_rho[i][j]) } } fclose(fileP); fclose(fileT); fclose(fileVar); Message("The code is entirely compiled"); } Can anyone find any mistake? Thank you, as always, for your help. EDIT: I also thought that maybe the problem does not lie in the UDF but in other conditions ( boundary, materials etc..) but I took an over-simplified model, and moreover this udf only needs to load external files without interacting with the model. |
|
December 10, 2021, 13:43 |
|
#9 |
Senior Member
Join Date: Nov 2013
Posts: 1,965
Rep Power: 27 |
Simplify further. Instead of trying to load three files, try one file.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build". |
|
December 12, 2021, 16:23 |
|
#10 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
Thank you pakk for your reply.
I tried to simplify but still no improvements. I realised that I’m not even able to execute a simple array from imported text. So the error could be in my .txt file. Does fluent read scientific notation (1.0e5) with %lf in fscanf or should I use %e? Could there be any problem with the .txt file itself? I could also try with a .dat Thank you for your help Gianmarco |
|
December 14, 2021, 11:25 |
|
#11 |
New Member
Gianmarco
Join Date: Nov 2021
Posts: 10
Rep Power: 5 |
I solved my problem. As always, in coding, the error is trivial. The problem lied in the scientific notation in my txt file. It seems that fluent is case sensitive to the notation and it requires exponential with lower case e (1e5 and not 1E5). My bad. Thank you all for your help.
Since we’re here I would like to ask something new about the specific heat. The define specific heat macro only allows to state cp as function of temperature at constant pressure. Is there a way to overcome this limit land express cp as function of both T and P? I was thinking about going through the definition of enthalpy. Does anyone know a possibile solution to this problem? |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
How to define the inlet using an Interpolation Functions or Data sheet? | IronLyon | CFX | 8 | June 12, 2024 18:00 |
UDF: Value too large for defined data type | silvi | Fluent UDF and Scheme Programming | 0 | November 18, 2015 16:52 |
udf explaination | Ijaz | Fluent UDF and Scheme Programming | 4 | May 8, 2012 05:24 |
udf define property on a wall surface | bzhu | Fluent UDF and Scheme Programming | 1 | November 27, 2011 12:10 |
[making animations] fclose fails to close files? | Mika | FLUENT | 0 | March 30, 2001 09:19 |