|
[Sponsors] |
October 20, 2022, 00:20 |
Bang-bang control in Fluent
|
#1 |
New Member
Jared
Join Date: Oct 2022
Posts: 6
Rep Power: 4 |
Hi all,
I am looking to implement a bang-bang control system so that when a component exceeds an allowable temperature (T_max), it is shut off, until the temperature returns below a second value (T_min), then it is turned on again. In other words, If T > Tmax, P = 0 If Tmax < T < Tmin, P = P (at previous time step) If T < Tmin, P = 4000 W/m^3 I have linked the source term in a cell zone to an expression - but the expression is undefined as it contains a circular reference. Is there a different way to do this, as it seems like a fairly innocuous request. Here's what I have so far anyway: Expression is called "cam_power". IF(Tc>Tmax, 0 [W*m^-3], IF(AND(Tc<Tmax,Tc>Tmin),cam_power,4000 [W*m^-3])) Appreciate any help I can receive! |
|
October 20, 2022, 01:17 |
|
#2 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
you may use UDF
look for define_profile macro
__________________
best regards ****************************** press LIKE if this message was helpful |
|
October 20, 2022, 05:28 |
|
#3 |
New Member
Join Date: Sep 2021
Posts: 7
Rep Power: 5 |
Hi,
I was able to do a similar simulation with just using expressions in 2020R1. Creating two points (my temp sensor locations) as report definitions and attaching them to a constant flux boundary as a piecewise eqn. (just like you did) worked just fine for me. However I only had two flux options, say 0 and 4000 as in your case. IF(Tc>Tmax, 0 [W*m^-3], IF(Tc<Tmin),4000 [W*m^-3]) would be how I approach it. By this way if your sensor temperature (Tc) exceeds your cutoff temperature (Tmax), flux is set to zero until the sensor sees Tmin. Other way around if it drops below Tmin, 4000 is applied until it goes above Tmax again. This way you can keep your system between Tmax and Tmin (you will have to account for peak overshoot). Try plotting the flux at your boundary with this method. You should be able to see a square signal. |
|
October 20, 2022, 17:13 |
|
#4 |
New Member
Jared
Join Date: Oct 2022
Posts: 6
Rep Power: 4 |
Thanks for the reply.
The issue I am facing with this suggestion is I must provide a false value for the second IF statement so that if it is in the range Tmin < Tc < Tmax it must have a value. As far as I know I can't access the data at the previous timestep to continue what it was doing before - or checking the temporal temperature gradient to see if it is cooling or heating |
|
October 20, 2022, 22:48 |
|
#5 |
New Member
Jared
Join Date: Oct 2022
Posts: 6
Rep Power: 4 |
Thanks, I was reluctant to learn UDF's but I guess it is unavoidable now. As far as I can tell, it seems I need to use the DEFINE_SOURCE macro for heat generation. I found the following from an old post which was very helpful but I am unsure how to progress it further how to write udf for a component source term on a wall ? Code:
#include "udf.h" DEFINE_ON_DEMAND(selecting_the_cells) { #if !RP_HOST Domain *d; Thread *t, *tc, *t0; face_t f; cell_t c, c0; d=Get_Domain(1); tc=Lookup_Thread(d,9); //thread pointer of the surface (the ID can be obtained from the boundary condition panel) //Loop through all the cell threads in the domain thread_loop_c(t,d) { //Loop through the cells in each cell thread begin_c_loop(c,t) { C_UDMI(c,t,0)=0; } end_c_loop(c,t) } begin_f_loop(f,tc) { c0=F_C0(f,tc); t0=THREAD_T0(tc); C_UDMI(c0,t0,0)=1; } end_f_loop(f,tc) #endif } DEFINE_SOURCE(energy_source, c, t, dS, eqn) { real source; if (C_UDMI(c,t,0)>0.) { source=1000.; dS[eqn]=0.; } else { source=0.; dS[eqn]=0.; } return source; } |
|
October 21, 2022, 01:42 |
|
#6 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
your exact request is unclear, as code above is doing other things, comparing to your first message.
code below is: - getting min, max and average temperatures of solid zone (in code it has ID = 9, in your model could be different) - defining source value depending on tmax - applying source Code:
#include "udf.h" real source = 0.0; DEFINE_EXECUTE_AT_END(calculate_source) { Domain *d; real tavg = 0.; real tmax = 0.; real tmin = 0.; real temp,volume,vol_tot; Thread *t; cell_t c; d = Get_Domain(1); /* Loop over all cell threads in the domain */ t=Lookup_Thread(d,9); /* thread pointer of the solid zone (the ID can be obtained from the boundary condition panel)*/ begin_c_loop(c,t) { volume = C_VOLUME(c,t); /* get cell volume */ temp = C_T(c,t); /* get cell temperature */ if (temp < tmin || tmin == 0.) tmin = temp; if (temp > tmax || tmax == 0.) tmax = temp; vol_tot += volume; tavg += temp*volume; } end_c_loop(c,t) tavg /= vol_tot; Message0("\n Tmin = %g Tmax = %g Tavg = %g\n",tmin,tmax,tavg); if (tmax > 500) source = 1000.0; else source = 0.0; } DEFINE_SOURCE(energy_source, c, t, dS, eqn) { return source; }
__________________
best regards ****************************** press LIKE if this message was helpful |
|
October 25, 2022, 20:05 |
|
#7 | |
New Member
Jared
Join Date: Oct 2022
Posts: 6
Rep Power: 4 |
Quote:
Great! That helped a lot. Here is my working code (some of it is a bit ugly and redundant as I didn't want to waste simulation time, but it works ) Code:
#include "udf.h" real source_p1 = 0; real source_p2 = 0; real source_p3 = 0; int state = 1; /* 1 is ON, 0 is OFF */ DEFINE_EXECUTE_AT_END(calculate_source) { real tmax = 0.; real tmin = 0.; real thigh = 315; /* allowable max */ real tlow = 310; /* allowable min */ real temp; /* ====== p1 ====== */ Domain *d; Thread *t; cell_t c; d = Get_Domain(1); t=Lookup_Thread(d,106); /* thread pointer of the solid zone (the ID can be obtained from the boundary condition panel)*/ /* ====== p2 ====== */ Domain *dp; Thread *tp; cell_t cp; dp = Get_Domain(1); tp=Lookup_Thread(dp,96); /* thread pointer of the solid zone (the ID can be obtained from the boundary condition panel)*/ /* ====== p3 ====== */ Domain *di; Thread *ti; cell_t ci; di = Get_Domain(1); ti=Lookup_Thread(di,1048); /* thread pointer of the solid zone (the ID can be obtained from the boundary condition panel)*/ begin_c_loop(c,t) /* Loop over all cell threads in the p1 domain */ { temp = C_T(c,t); /* get cell temperature using C_T*/ if (temp < tmin || tmin == 0.) tmin = temp; /* find min temp */ if (temp > tmax || tmax == 0.) tmax = temp; /* find max temp */ } end_c_loop(c,t) begin_c_loop(cp,tp) /* Loop over all cell threads in the p2 domain */ { temp = C_T(cp,tp); /* get cell temperature using C_T*/ if (temp < tmin || tmin == 0.) tmin = temp; /* find min temp */ if (temp > tmax || tmax == 0.) tmax = temp; /* find max temp */ } end_c_loop(cp,tp) begin_c_loop(ci,ti) /* Loop over all cell threads in the p3 domain */ { temp = C_T(ci,ti); /* get cell temperature using C_T*/ if (temp < tmin || tmin == 0.) tmin = temp; /* find min temp */ if (temp > tmax || tmax == 0.) tmax = temp; /* find max temp */ } end_c_loop(ci,ti) Message("\n Tmin = %g Tmax = %g\n",tmin,tmax); Message("\n Controller = %g\n",state); if (tmax > thigh) state = 0; /* turn off */ if (tmin < tlow) state = 1; /* turn on */ } DEFINE_SOURCE(p1_source, c, t, dS, eqn) { if (state == 1) source_p1 = 42900; else source_p1 = 0; return source_p1; } DEFINE_SOURCE(p2_source, cp, tp, dS, eqn) { if (state == 1) source_p2 = 25800; else source_p2 = 0; return source_p2; } DEFINE_SOURCE(p3_source, ci, ti, dS, eqn) { if (state == 1) source_p3 = 12200; else source_p3 = 0; return source_p3; } DEFINE_REPORT_DEFINITION_FN(control_state) { return state; } |
||
Tags |
conditional, expressions |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Fluent exit frequently with error ‘Unable to parse’ running on remote clusters | Gang Shen | Fluent Multiphase | 5 | February 7, 2022 04:02 |
Building problems with cell zones when reopening Fluent | MJ2017 | FLUENT | 0 | October 14, 2017 09:11 |
Error in reading Fluent 13 case file in fluent 12 | apurv | FLUENT | 2 | July 12, 2013 08:46 |
Problems in lauching FLUENT | Lourival | FLUENT | 3 | January 16, 2008 17:48 |
fluent transient simulation control | Kai Kang | FLUENT | 0 | January 20, 2000 13:52 |