CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (https://www.cfd-online.com/Forums/fluent-udf/)
-   -   Read txt file and import values to source term. (https://www.cfd-online.com/Forums/fluent-udf/73863-read-txt-file-import-values-source-term.html)

Constantine March 18, 2010 11:58

Read txt file and import values to source term.
 
Hello all,
I am trying to read some values from a txt file and import them as a source term to my grid's cells.
My udf code for a simple grid of 8 cells (i=2,j=4) with data like the following
1 2 3 4
5 6 7 8

is

#include "udf.h"


DEFINE_SOURCE(ymom_source,c,t,dS,eqn)
{

FILE *fp;
real source;

int i,j;

fp= fopen("force.txt","r");

while

(fscanf (fp,"%d",&c))
{


source=c;


dS[eqn] = 0.;



printf("Content of variable c is: %d",c);

printf("Content of variable source is: %d",source);
}

return source;


}


The problem is that the source term values are 0 !! I dont understand why, because the c variable of the cell which is printed on the screen is the right values for every cell!
Help pls! :P

sega March 18, 2010 12:49

I'm not sure, but maybe you even have to set the right value for dS?!
Just guessing in this case ..

Constantine March 18, 2010 13:02

No the dS term is just for helping the convergence ...by setting it equal to 0 i just force the explicit solution of the source term according to the UDF manual....the problem is not this ....and unfortunatelly i dont understand what is it!!!! :P
Thx anyway for your reply!

sega March 18, 2010 13:10

Quote:

Originally Posted by Constantine (Post 250678)
No the dS term is just for helping the convergence ...by setting it equal to 0 i just force the explicit solution of the source term according to the UDF manual....the problem is not this ....and unfortunatelly i dont understand what is it!!!! :P
Thx anyway for your reply!

Well, sometimes you have to activate your source term in the GUI.
(At least it's the fact when using the source termin with the Discrete Phase Model)
But I don't know where this is done for momentum...

Micael March 18, 2010 13:32

How did you hook your UDF to your model?

Constantine March 18, 2010 13:45

I interpreted it! I dont know if my UDF is finally right! The only thing i want to do is to read the data from the txt , put them in the cells and then make the source term be equal to this values in each cell! Even if i put the source=5 for example when i want to print it on the screen the value is 0!! :(

sega March 18, 2010 13:52

Its not done with compiling and loading your UDF.
Maybe you have forgotten to Hook Up the UDF as Micael suggested.

Chapter 6.2.19 in the UDF Manual (Version 12, April 2009)!

Constantine March 18, 2010 13:56

I have interpreted my UDF and then I hooked it on the fluid zone that has 8 cells (as many as the data values read from the txt file).It works without the reading of file if I just put a constant source in every cell so this it not the problem i suppose!

Micael March 18, 2010 19:47

Ok, I taked a time to analyse your UDF. Did you copy the code from other application and try to adjust it to your need? I do not have FLUENT at hand right now, but I think I see some errors.

1- the "c" variable is of cell_t type, it is passed by the solver to your UDF and contain the index of the current cell. Then, you use it as if it is a real.

2- I do not understand why there is a while loop. You should not compute every source in one pass with DEFINE_SOURCE. Actually, the solver will call DEFINE_SOURCE once for every cell, so it is already doing a loop.

3- You open a file, but never close it. It can be hard to say where fscanf is (which line it read in the text file). However, you cannot just closed it at the end of the UDF because it will cause fscanf to read the first line each time the solver call the function.

4- How do you know that you put the source value to the corresponding cell? I do not see any code to control it.

This UDF is likely to do something without error, but it does not what you expect it to do.

Does this make sense to you?

Have a good day

Micaël

Constantine March 18, 2010 20:16

Hello again,
yes of course you are right to everything!Well i did some progress i think!Now i have the values i want to the different cells! my code is the following

#include "udf.h"


DEFINE_SOURCE(ymom_source,c,t,dS,eqn)
{

FILE *fp;
real source[8];
real plasma[8];

int i,j;

fp= fopen("force.txt","r");

for (i=0;i<8;i++)
{
fscanf (fp,"%g\n",&plasma[i]);
}

fclose(fp);

for(j=0;j<8;j++)
{

source[j]=plasma[j];
}

dS[eqn]=0.0;

return source[c];
}

The problem now is that my data is not a [2][4] matrix but way bigger! And when im trying to write the data from matlab to txt the numbers become really nonstructured!! But I think this is for a matlab's forum and not for here! :P
Anyway I would be glad if you could help me, and any comment to my code would be useful of course!
Thank you so much for your responses!!!I have a feeling that Ill return here veeeery soon LOL !

Cheers!

Micael March 18, 2010 21:34

I am glad you push it further. So I will give you more hints.

The challenge here seems to be to return the proper source out of a list. It is not that obvious to know where is the cell based only on the variable "c". This variable is of type "cell_t", but it should still be an integer, so it maybe possible to use it like you do ("return source[c]"). Because you only have 8 cells, you could be able to manage to know how the index (cell_t) are spread on the grid, but that does not sound like a good practice (usually, model has a lot more than 8 cells).

One solution could be to analyse the coordinates (x,y) of the current cell (the one for which the solver calls DEFINE_SOURCE). Then, based on these coordinates, choose the corresponding source value. That would need a more advanced code, but a beginner can learn to do it. Check the UDF guide (look for C_CENTROID, it would be useful for that). Anyway, if you are sure what is the c value for each of your 8 cells, then your code could works as is.

You do not need to use the name "source" when you return. You could have just wrote: "return plasma[c];" and simplified a bit your code. The solver receives the value, not the name. Also, you do not need 2 "for" loops for what you do, you can merge them together.

On what the source depends on? If the model for it is simple, then it can be easier to model it right in the UDF.

Keep working.:)

Micaël

Constantine March 19, 2010 12:07

Hey Mikael,
I have managed to understand how the udf distributes the source in the grid's cells by 'playing' with my data values! I think I have understand its thinking,so I also think I would be able to apply this on my normal grid which is made of 30000 cells!
I have also thought of using the coordinates of each cell but I want my code as simplified as possible at for this moment it runs so im happy! :P
Thanks for the notes for the for loop and the source!
My source term is a force corresponding to the force thats being generated from a plasma actuator.The plasma flow modelling has already been done so the thing is to import the data to this small region (plasma region) for example on a flat plate!So for sure I can not model it inside the UDF ! Anyway its just a matter of pasting data!
Grrrr this thing drives me mad though...I still can't put the grid data into a text file without getting them all messed up! :(

Thanks anyway!!! Hope I have good results and news soon!

Constantine! :)

Micael March 19, 2010 14:08

Ok.

Now you have 30 000 cells. Be aware that your code will loop 30 000 times for each of you 30 000 cells. Yes, that is 900 000 000. I did not mention that before because of the very low amount of cell you had. I do not know how much time those extra computation will add. If you find out that computation takes long, let me know, I can show you a solution (but yea, that will need more coding from you).

Constantine March 19, 2010 15:38

aaaaaaaaaah!! yeah this is a problem i think!!!! The number of the loops make fluent crash!! :( I dont know why but on the fluent screen i have empty lines as many as the cells....and not even one iteration is being made! Is it due to the comp time huh??
I would be way than thankful if you could help me with this!!!!(coding let it be!) :)

Micael March 19, 2010 18:36

I do not expect the repetitive loop to make it crash. It should just slow down the iterations. That can be something else.

Anyway, it sounds like you need to do it the correct way once for good.

I suggest to write a separate function for reading the data and assign them to an array. You really need to do it only once so it should not be done in a DEFINE_SOURCE function. DEFINE_ON_DEMAND can do the job. That can just look like that:


/************************************************
UDF for reading data and assign them to an array
************************************************/


#include "udf.h"

extern float plasma[30000];

DEFINE_ON_DEMAND(read_data)
{
int i;
FILE *rfile; /* declare a FILE pointer */

rfile = fopen("data.txt", "r"); /* open file for reading */
Message("file opened\n");

/* loop to read file */
i=0; /* initialize before to loop */
for (i=0;i<30000;i++)
{
fscanf (rfile, "%f", plasma[i]); /* that supposes one value per line */
}

fclose(rfile);
Message("file closed\n");
}

Then just use your previous UDF, but quite simplify:

/************************************************** *****
UDF to define the source for each cells
That suppose that values of "c" match proper index in plasma[30000]
************************************************** *****/

#include "udf.h"

float plasma[30000];

DEFINE_SOURCE(ymom_source,c,t,dS,eqn)
{
dS[eqn]=0.0;
return plasma[c];
}


Save each of these into a *.c file. Then compile (build then load) the 2 files together. Once it is done, go the the "Execute on Demand" panel and execute "read_data". That will assign your data to plasma[]. Then the other UDF can use it.

I am still not sure you will go free of trouble with the way you match cell index with your data. The solution may not be complete yet...

You may want to add some code to read_data so that it writes back plasma[] into a text file. Just to make sure it do what you want.

I am please if it helps you. Actually, I just modify a little bit a UDF I already use for reading data, so that was not that difficult to me.

Constantine March 19, 2010 19:15

Hello Mikael again,
unfortunatelly this doesnt work! I dont know why but i cant compile the files...there is a message that the library couldnt be found when i load them!
Is it possible to do this with interpret???When i intrepret the read_data udf and then i try to execute on demand there is either an error of chip or an access violation!
Unfortunatelly I have no time now to search more! Ill be back on Sunday so that I will work on it! I hope that we can talk then! Thanks again 900000000 times (as many as the loops :P)
Have a nice weekend!

Micael March 19, 2010 20:14

You cannot just compile it like that. There is a special procedure to compile. Basically, you need Visual Studio installed on your computer and launch Fluent from the command prompt of Visual Studio. Visual C++ 2008 Express Edition should works and is free. Check the user guide about how to compile UDF. Some UDF will not works if interpreted, because there are some limitation in the C language you can use with interpret mode.

Constantine March 21, 2010 18:00

Hey Mikael,
Ive done everything as it has to be but as soon as i execute on demand the read data udf this error occurs
Error:
FLUENT received fatal signal (ACCESS_VIOLATION)!!
Do you have any idea what could cause this problem???

Constantine March 21, 2010 18:28

and also when im compiling the file with the
extern float plasma[30000];
line there is the following error
error LNK2019: unresolved external symbol _plasma referenced in function _read_data
libudf.dll : fatal error LNK1120: 1 unresolved externals

:(

Micael March 22, 2010 08:14

I'll check it tomorrow. Try a fluent tutorial with UDF (one that need to compile) to make sure you are doing everything right.

Micaël


All times are GMT -4. The time now is 19:23.