|
[Sponsors] |
UDF for reading a file filled with transient power data |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
New Member
Julius
Join Date: Mar 2020
Location: Aachen
Posts: 10
Rep Power: 6 ![]() |
Hi all together,
I want to simulate the following problem: there is a electric arc ignition between two electrodes inside a closed compartment (cube). This electric power is transformed into heat and then into pressure rise inside the closed compartment. And as a result of my simulation i want a pressure distribution on each wall of the outer compartment. So I tried to implement a UDF that reads a .txt file in which I have the power of the electric arc over time (consists out of two columns, column 1 is time in [s], column 2 is power in [W]). After reading the data it should "release the power in a specified volume or point. I started to read in the data and tried to store them in two vectors, one for the time (z) and one for the power (p). I want to release the energy in the middle of the cube x,y,z = (0,0,0) but I don't know how to tell the solver, that the energy is released in a specific volume or point. I guess I have to tell the solver the time from my .txt file and tell him that the source at this point of time is equal to this amount of power. But I dont know how Thanks for any hint! I attached the .txt file and my UDF |
|
![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
|
There are at least two ways you can do it; both ways do not require a UDF. And for both you need to know the location and size of zone where you want to apply the source.
1. Define a profile file. All you need to do is add two lines on top of your existing text file that contains data. First line contains name of profile, number of fields (columns), number of data points, and whether the data is time-periodic or not. Second line contains names for the fields. First name must be time. So, the two lines would be arcHeatSource 2 1000 0 Time energySource You have negative values for time in your file. Fluent will not accept those numbers. And all time values must be in ascending order. Then read this file via File > Read > Profile 2. Initialize your case. Go to Adapt, Region, and then choose the shape for the region where you want to apply source. It could be cylindrical, cuboid, or spherical. Provide the coordinates accordingly, such as, center point, height, and radius for cylinder. Then click on Mark. This will mark the cells as per given coordinates. 3. Go to Mesh > Separate > Cells. Use Register to separate the cell zone into two zones. It will separate the cells marked in previous step as a new cell zone. 4. Go to new cell zone conditions, enable source, then apply energy source using the profile. Other option is to create the region at the CAD level, mesh it, give it a separate name, and then load mesh in Fluent. Fluent will show two cell zones. Apply source using profile file in the cell zone representing the energy source region. Last option certainly is UDF, however, the approach you are using is very expensive. DEFINE_SOURCE goes to each and every cell at every iteration. If it has to read a static file each and every iteration for each cell, it will be very slow. So, you can read the file using DEFINE_ON_DEMAND or DEFINE_EXECUTE_ON_LOADING and assign values from the file to UDM 0. Within the same UDF, assign value of 1 to UDM 1 if cell is within the space of arc else assign a value of 0. Now, in DEFINE_SOURCE UDF, you can return a product of UDM 0 and UDM 1.
__________________
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. |
|
![]() |
![]() |
![]() |
![]() |
#3 |
New Member
Julius
Join Date: Mar 2020
Location: Aachen
Posts: 10
Rep Power: 6 ![]() |
Thank you for your reply!
First I tried the first version you wrote. And it is calculating at the moment. But I couldnt read in the file as you said. Fluent said in in the comand window that it will load the file, but nothing happend.. So i did it this way: ((power transient 950 0) (time 9.375e-09 0.0003 0.0006 0.0009 ...) (P 11748 2.7751e+05 6.1732e+05 7.0318e+05 ...)) But now when I want to assign the source term to the cell zone I can only choose between time and P.. I don't now if fluent needs the timestep aswell. And I dont' know why Fluent doesnt read the profile as you suggested.. Then I tried the last way with an UDF as you said, becaus I need an UDF becaus the project will get bigger and I need to add some subroutines in the future. So the UDF-way is the way I need to go. I dont get what you mean by "assign values from the file to UDM 0". What is UDM 0, where do I define it? Thats how my Source Code looks like at the moment: Code:
#include "udf.h" // UDf Grundlegende Headerdatei DEFINE_EXECUTE_ON_LOADING(open_Powerfile, libudf) { FILE* fp; // definiert einen lokalen pointer vom typ FILE //char* filename = "\\C:\Users\henke\Desktop\Ansys\Ansys\Power.txt"; fp = fopen("\\gdnts04\\user\\henke\\30.03.2020_Masterarbeit_Henke\\Software\\Ansys\\Power.txt", "r"); //* öffnet die Datei Power.txt im "nur lesen" Modus und weißt sie dem pointer fp zu double u[115000]; double n[115000]; if (fp != NULL) { while (!feof(fp)) { fscanf(fp, "%lf" "%lf", u, &n); fclose(fp); } } else { printf("Datei konnte nicht geoeffnet werden.\n"); } } DEFINE_SOURCE(local_energy_source,c,t,dS,eqn) { real x[ND_ND]; // array von Zellkoordinaten real source = 0.; // den Quellterm auf Null setzen //C_CENTROID(x,c,t); // ruft die Zellkoordinaten ab dS[eqn] = 0.; // Ableitung des Quellterms source = 1; // Nicht-Null-Quelle [Erzeugungsrate/Volumen z.B. W/m^3] return source; // Quelle wird an den solver zurückgegeben } I'm not quite sure if I did read the file correctly in order to handle the data in the Define_source. What do you think about it? I'm not good in programming in C.. Thank you so much! |
|
![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
|
When a profile file is used, you only need to hook the required variable. Fluent assumes that the first data is time, that's why the name has to be time. So, just hook P and it will work.
As far as UDF is concerned, you have to do a little more work since the simulation time in Fluent and the time data in File may not match. Either you have to do zeroth order interpolation or linear interpolation. With profile file, Fluent does linear interpolation. UDM is a C variable that can store any type of value, i.e., real, integer, or boolean. The specialty of UDM is that it is a vector and its size is always equal to number of cells in the domain. So, if you assign two UDMs, you can access those using C_UDMI(c, t, 0) and C_UDMI(c, t, 1) within any UDF. To assign UDMs, use User-Defined > Memory and then use arrows to assign two. Ensure that you initialize the UDMs with 0 values before use. To do that you may either use Initalize, if you are just starting the case, or patch. Within ON_LOADING function, identify the cells that need to have source applied and set their UDM0 to 1. You don't really need the second UDM since the source value is a scalar and not changing from cell to cell. So, you just need to fetch a value from the array that has the data from the file, multiply it by UDM0 and return it as source.
__________________
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. |
|
![]() |
![]() |
![]() |
![]() |
#5 |
New Member
Julius
Join Date: Mar 2020
Location: Aachen
Posts: 10
Rep Power: 6 ![]() |
Hi thanks for the answer!
How do I "identify the cells that need to have source applied"? I want to apply the values to the region i defined before with this method "Go to Adapt, Region, and then choose the shape for the region where you want to apply source" This how my code looks like at the moment: Code:
#include "udf.h" // UDf Grundlegende Headerdatei DEFINE_EXECUTE_ON_LOADING(read_PowerFile, libudf) //öffnet die PowerDatei nur einmal anstatt Sie in jeder Zelle in "Define_Source" zu öffnen { FILE* f = fopen("C:\\Users\\henke\\Desktop\\Ansys\\Ansys\\Power.txt", "r"); if (f == NULL) return 1; double tValues[950]; double pValues[950]; int i = 0; char c; while ((c = fgetc(f)) != EOF) { ungetc(c, f); fscanf(f, "%lf %lf", &tValues[i], &pValues[i]); //printf("t:"); //printf("%lf\n", tValues[i]); //printf("p:"); //printf("%lf\n", pValues[i]); i++; } fclose(f); int function get_p(time) for (n = 1; n < 950; n++) { real P_inter; time = 0; P_inter = pValues[n] + ((pValues[n + 1] - pValues[n]) / (tValues[n + 1] - tValues[n])) * (time - tValues[n]); } get_p = P_inter; end funtion get_p C_UDMI(c, t, 0); } DEFINE_SOURCE(local_energy_source,c,t,dS,eqn) { real x[ND_ND]; // array von Zellkoordinaten real source = 0.; // den Quellterm auf Null setzen C_CENTROID(x,c,t); // ruft die Zellkoordinaten ab dS[eqn] = 0.; // Ableitung des Quellterms source = get_p(time); // Nicht-Null-Quelle [Erzeugungsrate/Volumen z.B. W/m^3] return source; // Quelle wird an den solver zurückgegeben } Does it make sense to you? What can I do better? |
|
![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
|
To identify the cells, you need to know the definition of the region that you want to use for the identification, e.g., cells within a sphere located at (x0, y0, z0) with a radius of r0, or cells within a cuboid located with diagonal coordinates of (x0, y0, z0) and (x1, y1, z1). Then you can use C_CENTROID to fetch the coordinates of each cell and check if the centroid falls within the region or not.
__________________
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. |
|
![]() |
![]() |
![]() |
Tags |
.txt, energy equation, source term, udf, volume cell zone |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Using PengRobinsonGas EoS with sprayFoam | Jabo | OpenFOAM Running, Solving & CFD | 36 | July 16, 2024 03:52 |
how to calculate mass flow rate on patches and summation of that during the run? | immortality | OpenFOAM Post-Processing | 104 | February 16, 2021 08:46 |
[swak4Foam] funkyDoCalc with OF2.3 massflow | NiFl | OpenFOAM Community Contributions | 14 | November 25, 2020 03:30 |
[Other] Adding solvers from DensityBasedTurbo to foam-extend 3.0 | Seroga | OpenFOAM Community Contributions | 9 | June 12, 2015 17:18 |
"parabolicVelocity" in OpenFoam 2.1.0 ? | sawyer86 | OpenFOAM Running, Solving & CFD | 21 | February 7, 2012 11:44 |