CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   FLUENT (https://www.cfd-online.com/Forums/fluent/)
-   -   Monitor Points/Surfaces (https://www.cfd-online.com/Forums/fluent/225214-monitor-points-surfaces.html)

Mohinder Suresh March 18, 2020 13:25

Monitor Points/Surfaces
 
Hello, everybody,
i would like to address a topic which i think has a high relevance for the cummunity, namely the definition of monitor points/surfaces during a transient calculation. When it comes to LES simulations, you don't want to store the output of the whole domain at each time step in order to perform transient analysis. Therefore it is possible to define monitor points. In my case, however, these are 100k+ points, which are arranged in several planes. I have followed different ways to do this as efficiently as possible:
1: import monitor surface points via TUI -> this is possible up to a number of 2000 points, but then it gets exponentially slower and is therefore not an option.
2. import stl surfaces and imprint them via /surface/imprint-surface/... -> this would destroy the structured arrangement of my data, which I could live with but even this approach is so slow that it is absolutely impractical.
3. the last solution is of course an implementation using UDF. I found a function for this (https://www.eureka.im/701.html), but it is from 2003 and I wonder if this is really the most efficient way to define such an output, especially since it is completely trivial in CFX using user interfaces? (I have not been able to get this solution to work! -> SIGSEV error!)
I hope that people who understand more of the material can help me and above all I hope that this is really just a mistake on my part, because I think that this would really be a weakness of the pre processing of fluent.

vinerm March 19, 2020 03:54

Monitor Points
 
For such a high number of data points, it is obvious for any tool to slow down. But the reason is not the tool, rather the machines I/O. For such a work, you need to have hard drive working at the speed of RAM, i.e., an SSD.

Even if you use UDF, it will be slow, however, the UDF will work for sure. Furthermore, if you want to write data only for a few variables, you may also go for option of writing cdat files from Fluent. This will store more data but will still be much smaller than Fluent's dat file.

SIGSEGV error implies that UDF is trying to access an unavailable memory. The specified UDF requires gradients of the field variables to be stored. By default, Fluent does not store those values. As mentioned in the Note, a command is required to be issued before running Fluent. If that is not issued, you will get segmentation violation error. This will also increase the RAM requirement because now you have many more matrices to be saved.

Mohinder Suresh March 19, 2020 04:53

Hello, vinerm,
first of all I would like to thank you for the quick response. I have worked with CFX for many years and there the insertion of monitorpoints or user interfaces is very comfortable and also possible without noticeable delay. Maybe that's why I am a bit spoiled. In fact I think that the variant using the UDF is the best option and of course I have set the expert parameter correctly according to the instructions, but I still get the error message.
I also have a webex with the ansys support today. If they can offer me a working solution I can announce it here!
Thanks again and many greetings
Mohinder

vinerm March 19, 2020 05:02

CFX/ Fluent
 
I suppose that's subjective. Fluent users find CFX interface rather clumsy. I use both, though more of Fluent. But I have never heard of user interfaces in CFX. Do you mean user surfaces? Or is it something new?

Good that you have a webex planned with Ansys today. I hope they resolve the issue. You can certainly post the status, including if you need help with the UDF.

Mohinder Suresh March 19, 2020 05:55

Hello, vinerm,
excuse me I meant user surfaces of course! These are indeed solved very comfortably in CFX, because it is possible to save the data structured in this way.
Regards

vinerm March 19, 2020 06:08

Arrays and Groups
 
If the points are not arbitrarily distributed on planes, then you can still go for point arrays and groups. That will reduce the number of monitors as well as number of files. However, now the data will be listed by node number and their locations instead of, say, by point names. But this would make it manageable. The output will be similar to what you get from CFX, a comma or space separated file.

LuckyTran March 19, 2020 06:34

Quote:

Originally Posted by Mohinder Suresh (Post 762077)
Therefore it is possible to define monitor points. In my case, however, these are 100k+ points, which are arranged in several planes.


Do you actually want 100k distinct points? Why can't you just make several planes? I've never known of anyone to actually desire 100k distinct points, keep track of them, and do post-processing this way. Heck, back in 32-bit excel, there weren't even 100k lines for you to even write down all your points.

Mohinder Suresh March 19, 2020 10:22

Vinerm,
I dont know the function of point arrays and lists? Can you explain how this is done in fluent?
Regards

Mohinder

Mohinder Suresh March 19, 2020 10:28

Lucky Tran,
the reason is that I have 70million elements in my mesh and I need highly time resolved data output (3D) in the region of interest (near a turbine blade).

Ansys support told me to mark the cells near the blade via "mark/addapt cells -> boundary" and then split this reagion to enable a distinct 3D output in the near blade region!
I will try this and update you if this is working out for me!
Greets

Mohinder

vinerm March 19, 2020 10:42

Point Array and Cell Marking
 
If all the points are located in a specified region, then Marking the cells is a better idea. Point array would work for a cuboid region, not for a region shaped like a blade, which you most likely need. Earlier you mentioned that the points are on planes, that's why I mentioned point arrays. But if you want region around the blade(s), better mark those using Mark under Adapt. Then, separate those from the rest of the cell zone.

Point arrays are available under surface command.

Mohinder Suresh March 21, 2020 13:03

The workaround with the marked cells worked quite well for me!

Nevertheless, im interested to get the UDF, working!


I managed to compile the udf and it is reading the coordinates from the input file, but then it crashes with an SIGSEGV error.



Now I want to debug the UDF using Messages, but unfortuantely no message/message0 are plotted in the out file! The messages are only plotted if the udf is in the #if RP_HOST mode. Is there a way to see the messages even if in #if !RP_HOST mode?

Sorry im not experienced in UDF.



Greets Mohinder

Mohinder Suresh March 21, 2020 13:54

The UDF for the file-read of the monitor point coordinates is:
Code:

#include "udf.h"
#include "surf.h"

#define MAXPOINTS 300000

#define NSCALARS (1+ND_ND)

real coords[MAXPOINTS][ND_ND];
int total_count;
#if !RP_HOST

int total_points_found;

struct interpolation_point{
#if PARALLEL
int partition;
int highest_partition;
#endif
cell_t c;
Thread* t;
cxboolean found;
};

struct interpolation_point point_list[MAXPOINTS];
cxboolean interpolation_initialized;

/* Function Prototypes */
cxboolean is_point_in_cell(cell_t c, Thread* t, real* x);

#endif


DEFINE_ON_DEMAND(read_points)
{

#if !RP_HOST
Domain* d = Get_Domain(1);
Thread* t;
cell_t c;
int i, point;
#endif


#if !RP_NODE

char* input_file_name = "interp.inp";

FILE* input;
int n, m;

for(n=0; n<MAXPOINTS; n++)
for(m=0; m<ND_ND; m++)
coords[n][m] = 0.0;

n = 0;

input = fopen(input_file_name, "r");

while(!feof(input))
{
#if RP_DOUBLE
#if RP_3D
fscanf(input,"%lg %lg %lg\n", &coords[n][0], &coords[n][1], &coords[n][2]);
Message("%12.9e %12.9e %12.9e\n", coords[n][0], coords[n][1], coords[n][2]);
#else
fscanf(input,"%lg %lg\n", &coords[n][0], &coords[n][1]);
#endif
#else
#if RP_3D
fscanf(input,"%g %g %g\n", &coords[n][0], &coords[n][1], &coords[n][2]);
#else
fscanf(input,"%g %g\n", &coords[n][0], &coords[n][1]);
#endif
#endif

n++;

if (n == MAXPOINTS)
{
Message("\n\nWARNING: Number of points in input file has exceeded MAXPOINTS, which is set to %i\n", MAXPOINTS);
Message(" Recompile UDF with MAXPOINTS >= number of data points in input file.\n");
Message(" ... only %i points will be processed...\n\n", MAXPOINTS);
break;
}
}

total_count = n;

Message("\n\nThere are %i sets of coordinates read from input file.\n",total_count);

fclose(input);

#endif


/* Initialize coordinates on COMPUTE NODES */
host_to_node_int_1(total_count);
host_to_node_real(&coords[0][0],ND_ND*MAXPOINTS);
#if !RP_HOST
interpolation_initialized = FALSE;

for(point=0; point<total_count; point++)
{
point_list[point].found = FALSE;
}
/* Search over all cells */
thread_loop_c(t,d)
{
begin_c_loop_int(c,t)
{

for(point=0; point<total_count; point++)
{
if (point_list[point].found == FALSE)
{
if (is_point_in_cell(c,t,coords[point]))
{
#if PARALLEL
point_list[point].partition = myid;
#endif
point_list[point].c = c;
point_list[point].t = t;
point_list[point].found = TRUE;
}
}
}
}
end_c_loop_int(c,t);
}

total_points_found = 0;

#if PARALLEL
for(point=0; point<total_count; point++)
{
point_list[point].highest_partition = PRF_GIHIGH1(point_list[point].partition);
point_list[point].found = PRF_GIHIGH1(point_list[point].found);
}
#endif
#endif
#if !RP_HOST
for(point=0; point<total_count; point++)
{
if (point_list[point].found)
{
#if PARALLEL
if (myid == point_list[point].highest_partition)
#endif
total_points_found++;
}
else
{
Message0("Could not find point %i: (", point+1);
for(i=0; i<ND_ND; i++)
Message0(" %12.5e ", coords[point][i]);
Message0(") in the domain.\n");
}
}
#if PARALLEL
total_points_found = PRF_GRSUM1(total_points_found);
#endif
#if PARALLEL
if (total_points_found == total_count)
{
Message0("\nAll points were successfully located.\n");
interpolation_initialized = TRUE;
}
else
{
Message0("ERROR: All points have not been located.\n");
interpolation_initialized = FALSE;
}
#endif
#if PARALLEL
interpolation_initialized = PRF_GRLOW1(interpolation_initialized);
#endif
#endif
return;
}



#if !RP_HOST

cxboolean is_point_in_cell(cell_t c, Thread* t, real* x)
{

int i;
face_t f;
Thread* tf;
real A[ND_ND], n[ND_ND], v[ND_ND], face_centroid[ND_ND], z[ND_ND], cell_centroid[ND_ND];
real Amag;

/* Center of cell */
C_CENTROID(cell_centroid,c,t);

/* Loop over all faces of cell */
c_face_loop(c,t,i)
{
/* Face i of cell*/
f = C_FACE(c,t,i);
tf = C_FACE_THREAD(c,t,i);

/* Face normal */
F_AREA(A,f,tf);

/* Probably sufficient to work with A, but normalizing it
will reduce truncation error */
Amag = NV_MAG(A);
NV_VS(n, =, A, /, Amag);

/* Centroid on face i */
F_CENTROID(face_centroid,f,tf);

/* Vector from face centroid to point x */
NV_VV(v, =, x, -, face_centroid);

/* Vector from cell centroid to face centroid */
NV_VV(z, =, face_centroid, -, cell_centroid);

/* Perform test to make sure face normal points outwards */
if (NV_DOT(n,z) < 0.0) NV_S(n,*=,-1.0);

/* If n.v > 0, then point is beyond "plane" that defines the face
and it cannot be inside the cell */
if (NV_DOT(n,v) > 0.0) return FALSE;

}

/* Otherwise it must be in the cell */
return TRUE;
}

#endif


vinerm March 22, 2020 04:19

Debugging
 
Do you get segmentation violation just by running this part of the code? I did not see anything that should cause it but there could be potential bugs, could also be due to version difference. Anyway, Message0 implies Message only from node0. So, it will work within !RP_HOST but only when it is node0 that is doing the processing. However, Message works everywhere. Each node should give message. The messages are printed in any out file, rather within Fluent's text interface, where all the residuals are printed. Those will be in a file if you run Fluent in batch. If messages are not appearing, then most likely Fluent does reach that level, either because it is within certain logical condition and the condition is not met or it is in a loop and the loop does not run.

Mohinder Suresh March 22, 2020 04:37

Hi vinerm,
thank you for your answer! The last Message i recieve in the out-file is

Code:

5.127923322e-01 6.856886251e-02 6.283185307e-03
5.125033958e-01 6.866966097e-02 6.283185307e-03
5.122016173e-01 6.876010789e-02 6.283185307e-03


There are 201150 sets of coordinates read from input file.

===============Message from the Cortex Process================================

Fatal error in one of the compute processes.

==============================================================================


And even if I replace every Message0 with Message I dont get any further messages inside the out file =| even if I put it directly behind



Code:

total_count = n;

Message("\n\nThere are %i sets of coordinates read from input file.\n",total_count);

fclose(input);

#endif


/* Initialize coordinates on COMPUTE NODES */
host_to_node_int_1(total_count);
host_to_node_real(&coords[0][0],ND_ND*MAXPOINTS);
#if !RP_HOST
Message("BREAK POINT 1");
interpolation_initialized = FALSE;


That is so weird =|

Mohinder Suresh March 22, 2020 04:46

My journal file for the testing is:


Code:

file/read-case Steady.cas
/solve/init/init
;
/define/user-defined/compiled-functions compile libudf yes "InterpFlowValues.c" "" ""
/define/user-defined/compiled-functions load "libudf"
/solve/execute-commands/add-edit read-points 5 "iteration" "/define/user-defined/execute-on-demand \"read_points::libudf\""

;
solve/iterate 10

;file/write-data Steady.dat
exit yes


vinerm March 22, 2020 04:49

Message
 
That means it is not even going beyond #if !RP_HOST, which is weird. Did you try this in Serial?

vinerm March 22, 2020 04:51

Journal
 
I just saw your journal. What is the objective of executing the reading UDF again and again? Are there any changes in the input file? If not, read it just once.

Mohinder Suresh March 22, 2020 05:10

Hi venerm,
of course you are right, this is not needed but it shouldnt affect the testing I think.

Thank you for the advice to try it in serial mode. I tried with the -t0 option but there are still some errors appearing allthough it doesnt crash

PS: Thank you very much for your help!



Code:

> ;
solve/iterate 10

  iter  continuity  x-velocity  y-velocity  z-velocity          k      omega    intermit    retheta    time/iter
    1  1.0000e+00  1.0468e-03  7.0191e-04  0.0000e+00  1.1951e+00  5.7785e+01  4.9000e-03  9.8251e-04  0:02:48    9
    2  8.3407e-01  2.5618e-03  2.7366e-03  0.0000e+00  7.9154e-01  9.0018e-01  1.8160e-03  1.0196e-03  0:02:11    8
    3  1.0000e+00  1.8218e-03  2.8778e-03  0.0000e+00  3.4192e-01  6.8517e-01  1.3752e-03  1.3013e-03  0:01:40    7
    4  5.7379e-01  1.5442e-03  2.3901e-03  0.0000e+00  5.3849e-02  2.7275e-01  1.3321e-03  1.3873e-03  0:01:16    6

Error:  received a fatal signal (Segmentation fault).

Error:  received a fatal signal (Segmentation fault).
Error Object: #f
/define/user-defined/execute-on-demand "read_points::libudf"4.254112840e-01 1.176838018e-02 6.283185307e-03
4.253465831e-01 1.171087101e-02 6.283185307e-03
4.252867699e-01 1.164679322e-02 6.283185307e-03
4.252322614e-01 1.157668698e-02 6.283185307e-03
4.251831770e-01 1.150115207e-02 6.283185307e-03
4.251398146e-01 1.142098289e-02 6.283185307e-03
4.251021445e-01 1.133669261e-02 6.283185307e-03
4.250703156e-01 1.124884281e-02 6.283185307e-03
4.250442386e-01 1.115792151e-02 6.283185307e-03
4.250235558e-01 1.106441207e-02 6.283185307e-03
4.250078797e-01 1.096876617e-02 6.283185307e-03
4.249967635e-01 1.087140664e-02 6.283185307e-03
4.249896407e-01 1.077238657e-02 6.283185307e-03


There are 13 sets of coordinates read from input file.
BREAK POINT 1

    5  3.9776e-01  1.3068e-03  1.9298e-03  0.0000e+00  9.8159e-03  4.8774e-02  1.3622e-03  1.2635e-03  0:00:57    5
    6  2.7749e-01  1.0907e-03  1.5447e-03  6.8925e-20  4.0420e-03  1.3768e-02  1.5719e-03  1.1275e-03  0:00:42    4
    7  1.9085e-01  9.5771e-04  1.2718e-03  5.6905e-20  2.5575e-03  6.8222e-03  1.5130e-03  9.3098e-04  0:00:30    3
    8  1.2826e-01  8.7905e-04  1.0656e-03  5.3668e-20  2.1761e-03  3.4904e-03  1.5708e-03  8.6323e-04  0:00:19    2
    9  8.5993e-02  8.3199e-04  8.9641e-04  3.4830e-20  2.1751e-03  2.7483e-03  1.9634e-03  7.7068e-04  0:00:09    1

 reversed flow in 69 faces on pressure-outlet 4.

Error:  received a fatal signal (Segmentation fault).

Error:  received a fatal signal (Segmentation fault).
Error Object: #f
/define/user-defined/execute-on-demand "read_points::libudf"4.254112840e-01 1.176838018e-02 6.283185307e-03
4.253465831e-01 1.171087101e-02 6.283185307e-03
4.252867699e-01 1.164679322e-02 6.283185307e-03
4.252322614e-01 1.157668698e-02 6.283185307e-03
4.251831770e-01 1.150115207e-02 6.283185307e-03
4.251398146e-01 1.142098289e-02 6.283185307e-03
4.251021445e-01 1.133669261e-02 6.283185307e-03
4.250703156e-01 1.124884281e-02 6.283185307e-03
4.250442386e-01 1.115792151e-02 6.283185307e-03
4.250235558e-01 1.106441207e-02 6.283185307e-03
4.250078797e-01 1.096876617e-02 6.283185307e-03
4.249967635e-01 1.087140664e-02 6.283185307e-03
4.249896407e-01 1.077238657e-02 6.283185307e-03


vinerm March 22, 2020 05:43

Error
 
The effect of reading again could cause error if Fluent tries to rewrite a memory while it should not be rewritten. So, instead of reading it using Execute-Command, read it within the journal by using the command just once. See if it still gives error. Once segmentation fault appears, Fluent usually gets stuck, however, that depends on whether the error flushes the cache or not. This one does not seem to be doing that, hence, Fluent runs despite the error.

Mohinder Suresh March 22, 2020 05:57

Hi vinerm,
thanks for the advide, I changed it but its giving the same error. But at least now i get the break point messages so I will try to debug the udf further in order to find the point where it is giving the error! hopefully I will be able to get it working...



Thank you very much for your help!

vinerm March 22, 2020 06:04

Good
 
That's good. Let me know if you need further help.

Mohinder Suresh March 24, 2020 01:11

Good morning vinerm,
thanks to your help, i was able to get the UDF working (at least in serial mode)! It is perfectly doing what it is supposed to be now and when I finnished the parallelization I will post the final solution here!
Now I am wondering if it is possible to also interpolate the q-criterion in these desired points! I've read some threads regarding custom field functions and user defined scalars, but i dont know what will be the most elegant solution as I not only need the values of Q in the cell centers, but also the derivatives for the final interpoaltion!
Do you have any suggestions how to approach this problem?

Thanks in advance!!


Mohinder

vinerm March 24, 2020 02:53

Q-Criterion
 
As far as defining a Custom Field Function is concerned, it is easy. You can refer the following

useful-les-tools-fluent

As far as UDF is concerned, though strain rate is directly available, vorticity is not. So, you have to use velocity gradients to define Q-criterion. You can fetch gradients or reconstruction gradients using C_DUDX(c, t), C_DUDY(c, t), etc. These can also be fetched using C_U_G(c, t)[0], where 0 implies x and so on.

You may have to issue the following command in your setup before the gradients become available because Fluent does not store those values.

solve set expert

And then Yes as a response to the question to keep the temporary memory from being freed. Then using these gradients, you can define q-criterion and write it to file.

Mohinder Suresh March 26, 2020 06:59

Thank you for your reply!
I think that both ways only give me the values of q at the node centers, but I also need the gradients of q to finally interpolate the value at the desired monitor points. Is there a way to also get access to the gradients of q?


Greets

Mohinder

vinerm March 26, 2020 07:05

Q gradients
 
As such, q-criterion is not defined as a primitive variable in Fluent. Therefore, its gradients are not available as well. So, the only way is to determine its gradient from its definition (using a pencil and paper) and then make use of that equation to determine its gradients within UDF. Do note that all values starting with C_ are cell center based. To fetch values at nodes, you have to loop over nodes.

Mohinder Suresh March 26, 2020 07:12

Yes, that would be a solution...
but I also found this example in the manual (example2)
Do you think that this would also be an option?

https://www.afs.enea.it/project/nept...udf/node20.htm

vinerm March 26, 2020 07:16

Uds
 
This will increase an equation in your case. Fluent solves full conservation equation for UDS. In my view, this would be an overkill just to fetch q-criterion at some points. Secondly, you have to ensure that despite UDS being solved, its values are determined on the basis of velocity gradients.

Mohinder Suresh March 26, 2020 07:17

Im referring o this post:
https://www.cfd-online.com/Forums/fl...-function.html

vinerm March 26, 2020 07:21

Cff
 
There are no options (nor is there any requirement) to determine gradients of CFF. Gradients are available only for field variables. CFF is a field variable but an algebraic one. So, only those fields for which conservation equation is solved need their gradients because flux need to be determined at the faces for solving the equation.

kont87 April 1, 2022 09:32

Quote:

Originally Posted by Mohinder Suresh (Post 762615)
Good morning vinerm,
thanks to your help, i was able to get the UDF working (at least in serial mode)! It is perfectly doing what it is supposed to be now and when I finnished the parallelization I will post the final solution here!
Now I am wondering if it is possible to also interpolate the q-criterion in these desired points! I've read some threads regarding custom field functions and user defined scalars, but i dont know what will be the most elegant solution as I not only need the values of Q in the cell centers, but also the derivatives for the final interpoaltion!
Do you have any suggestions how to approach this problem?

Thanks in advance!!


Mohinder

Hello Mohinder,

Did you manage to use the code in parallel?
I want to extract Cp and V from more than 2000 points, which are defined in a separate file(as was in your case)
I used your udf to test it, I appreciated, however, when I try to use it in parallel cores (160 cores) it gives me an error, and it seems that udf needs parallelization.
I am a newbie in udf usage, any help is welcome.
Regards

Sergen

AlexanderZ April 5, 2022 01:06

show your code and error log if you need help


All times are GMT -4. The time now is 17:05.