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!


All times are GMT -4. The time now is 08:14.