|
[Sponsors] |
How does connectivity macros work for cell zones |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
New Member
Doruk Yelkenci
Join Date: Apr 2017
Posts: 20
Rep Power: 9 ![]() |
Hello everyone,
I am trying to find values of the adjacent cells of a cell and then use these values for the cell. I have found F_C0 and F_C1 macros from the help but using these macros are not explained clearly. For example if a cellzone with only hex elements, C1 is the index for all the cells around C0 so it must consist of 6 cells. So if i use C_T(c1,t), from which of these cell it takes its value? or just finds the average of all C1 cells ? |
|
![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Join Date: Sep 2017
Posts: 246
Rep Power: 11 ![]() |
Hi Doruk,
F_C0 and THREAD_T0 look up the cell adjacent to a *face*, not a cell. For an interior face, there is also a cell on the other side, F_C1 and THREAD_T1. So, if you want to look up all the cells that lie adjacent to a specific cell, you need to loop over all faces of that cell, and for each face work out whether (c0,t0) or (c1,t1) is the neighbour. Remember that some faces of some cells will be boundary faces, with no neighbouring cell; and some neighbouring cells might be solid cells, which do not have fluid-style data Fluent has many capabilities, and this can lead to difficult cases: hanging nodes, dynamic mesh, adaption, non-conformal interfaces, etc. When you start looking at neighbouring cells, it is difficult to write UDFs that can deal with all these capabilities, and you should probably try to deal with only the ones relevant to your case -- just be aware that your UDFs will work on a restricted feature set. The most frequent complication is running in parallel. This will mean that some neighbours of a cell might "belong" to different partitions, perhaps on physically separate computers. The good news is that one layer of neighbours is copied over from these other partitions. So, looking at neighbours is safe in parallel -- so long as you only loop over interior cells. Look for documentation of the "interior cell looping macro" begin_c_loop_int. It is extremely difficult to look at neighbours-of-neighbours in parallel. So, here's a skeleton of the code you might want: Code:
Thread *t,*tf,*t0,*t1,*tn; cell_t c,c0,c1,cn; face_t f; int n; ... here find the cell-thread t that you want to work on begin_c_loop_int(c,t) { c_face_loop(c,t,n) { f = C_FACE(c,t,n); tf = C_FACE_THREAD(c,t,n); c0 = F_C0(f,tf); t0 = F_C0_THREAD(f,tf); c1 = F_C1(f,tf); t1 = F_C1_THREAD(f,tf); tn = NULL; if(t0 != NULL && (c != c0 || THREAD_ID(t0) != THREAD_ID(t))) { /* ... (c0,t0) is a neighbouring cell */ tn = t0; cn = c0; } else if(t1 != NULL && (c != c1 || THREAD_ID(t1) != THREAD_ID(t))) { /* ... (c1,t1) is a neighbouring cell */ tn = t1; cn = c1; } if(tn != NULL) { ... do something with the neighbour (cn,tn) here ... (not forgetting to check, for example, solid cell zones) } } } end_c_loop_int(c,t) Best regards, Ed |
|
![]() |
![]() |
![]() |
![]() |
#3 |
New Member
Doruk Yelkenci
Join Date: Apr 2017
Posts: 20
Rep Power: 9 ![]() |
Hi Ed,
Thanks for taking time to explain. I think I understand now. An interior face is between 2 cells. Such as 1223th face is between 7987th cell and 3435th cell c1 and c0 respectively. 3435th cell has 6 faces, 1223th face 2345th face, .... etc. and C1 varies for each face. For a simple case where all the cell elements are cube with same dimensions, Lets say if i want to find the neighboring cell at the top of a cell, I should just find the face at the top of c0 by coordinates of face compared to c0, then ask for c1. In code; begin_c_loop_int(c,t) { c_face_loop(c,t,n) { f = C_FACE(c,t,n); tf = C_FACE_THREAD(c,t,n); c0 = F_C0(f,tf); t0 = F_C0_THREAD(f,tf); c1 = F_C1(f,tf); t1 = F_C1_THREAD(f,tf); C_CENTROID(xc,c0,t0); F_CENTROID(xf,f,tf); if(xf[2]>xc[2]) { C_UDMI(c,t,1)=C_T(c1,t1); } We can make a workaround in parallel by giving all the necessary data to the node-zero then making calculations only for node zero and after that sending the data to all other nodes. I have done something like this when global reduction macros was bugged for my case and there is an example of it in user guide. It can make simulation very slow for some cases(when element number is very high or using super computer with 100 cores) but it works nonetheless. Best Regards, Doruk |
|
![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
Arun raj.S
Join Date: Jul 2011
Posts: 205
Rep Power: 16 ![]() |
Hello guys, I have a similar problem as yours. I would like to apply DEFINE_SOURCE only on the interior face. Is there any way you can help me with the UDF?
|
|
![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
|
Sources are volumetric and a source for a face is nothing but a flux. So, either apply a flux or apply sources in the cells adjacent to the faces.
__________________
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. |
|
![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Arun raj.S
Join Date: Jul 2011
Posts: 205
Rep Power: 16 ![]() |
Dear Vinerm, Thank you for your reply. How to apply sources to the cells adjacent to the interior or wall. I have made the source term as below. I did based on ID.
#include "udf.h" #include "math.h" #define M 18.015 #define hfg 2600000.0 #define R 8314.0 #define pi 3.141592 #define pref 101325 #define Tref 373.15 #define pv 15828.0 #define Tv 343.0 DEFINE_SOURCE(massliqcond,c,t,dS,eqn) { real source, pv_eq, Tlv, vol; Domain *d=Get_Domain(1); int ID=11; Thread *t_int=Lookup_Thread(d, ID); face_t f; real A[ND_ND]; real area = 0.0; { begin_c_loop(c,t) { int i = 0; f=C_FACE(c,t,i); F_AREA(A,f,t_int); area = 2*pi*NV_MAG(A); Tlv = C_T(c,t); vol = C_VOLUME(c,t); pv_eq = pref * exp(((M*hfg)/R) * ((1/Tref)-(1/Tlv))); source = 0.857142857 * (area/vol) * (1/pow(M/2*pi*R, 0.5)) * ((pv_eq/pow(Tlv, 0.5)) - (pv/pow(Tv, 0.5))); dS[eqn] = 0.857142857 * (area/vol) * (1/pow(M/2*pi*R, 0.5)) * (pref * exp((M*hfg)/R) * (-((1/Tref) * (0.5/pow(Tlv, 1.5))) + (1.5/pow(Tlv, 2.5)))); } end_c_loop(c,t) } return source; } |
|
![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
|
It has to be done in two parts
First, identify the cells where source needs to be added, such as, all the cells adjacent to a particular boundary. If these cells are fixed, i.e., their number and identification, then you can also separate those out as a separate cell zone. If you do not want to do that, then run a DEFINE_ON_DEMAND function that goes over the face loop of the boundary. While going over each face, identify the cell adjacent to each face, i.e., F_C0 and THREAD_T0. Using return values of these two function, assign a value of 1 to UDMs in these cells. In DEFINE_SOURCE, multiply the source with these UDMs. Now, source will be applied only in those cells that have UDM of 1. For all other cells, UDM should be initialized 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. |
|
![]() |
![]() |
![]() |
![]() |
#8 |
Senior Member
Arun raj.S
Join Date: Jul 2011
Posts: 205
Rep Power: 16 ![]() |
Thank you so much. This is what I am expecting as I don't have much idea about UDF development. May I know in which scenario we need to use DEFINE_DEMAND and DEFINE_ADJUST.
|
|
![]() |
![]() |
![]() |
![]() |
#9 |
Senior Member
|
DEMAND is based on user demand, whenver user wants to execute it. This can done using GUI or by giving a command in the text user interface or under Execute Commands. In other words, DEFINE_DEMAND is not executed by Fluent if user does not demand for it at specific intervals or at specific instant. On the other hand, DEFINE_PROFILE needs to be hooked to a physical zone, such as, a boundary or a cell zone. Fluent will execute it every iteration or based on the profile update interval chosen by the user under Run Calculation.
__________________
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. |
|
![]() |
![]() |
![]() |
![]() |
#10 |
Senior Member
Arun raj.S
Join Date: Jul 2011
Posts: 205
Rep Power: 16 ![]() |
I want to know about DEFINE_ADJUST. Thank you
|
|
![]() |
![]() |
![]() |
![]() |
#11 |
Senior Member
|
DEFINE_ADJUST is executed at the beginning of every iteration, before the fields are solved.
Refer the documentation for the details of all the DEFINE_ macros.
__________________
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. |
|
![]() |
![]() |
![]() |
![]() |
#12 |
Senior Member
Arun raj.S
Join Date: Jul 2011
Posts: 205
Rep Power: 16 ![]() |
Thanks a lot. I got it now.
|
|
![]() |
![]() |
![]() |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Building problems with cell zones when reopening Fluent | MJ2017 | FLUENT | 0 | October 14, 2017 08:11 |
how to work on parallel computing in openfoam.. Machine to machine connectivity | Thomas Renald | OpenFOAM Running, Solving & CFD | 0 | October 21, 2016 05:31 |
First order in fvSchemes does not seem to work | gerritgroot | OpenFOAM Running, Solving & CFD | 0 | September 30, 2015 20:06 |
[Gmsh] Cell to node connectivity after 'gmshToFoam' | Jibran | OpenFOAM Meshing & Mesh Conversion | 1 | June 8, 2015 09:09 |
ATTENTION! Reliability problems in CFX 5.7 | Joseph | CFX | 14 | April 20, 2010 15:45 |