|
[Sponsors] |
March 18, 2020, 14:25 |
Monitor Points/Surfaces
|
#1 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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. |
|
March 19, 2020, 04:54 |
Monitor Points
|
#2 |
Senior Member
|
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.
__________________
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. |
|
March 19, 2020, 05:53 |
|
#3 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 19, 2020, 06:02 |
CFX/ Fluent
|
#4 |
Senior Member
|
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.
__________________
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. |
|
March 19, 2020, 06:55 |
|
#5 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 19, 2020, 07:08 |
Arrays and Groups
|
#6 |
Senior Member
|
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.
__________________
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. |
|
March 19, 2020, 07:34 |
|
#7 | |
Senior Member
Lucky
Join Date: Apr 2011
Location: Orlando, FL USA
Posts: 5,746
Rep Power: 66 |
Quote:
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. |
||
March 19, 2020, 11:22 |
|
#8 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
Vinerm,
I dont know the function of point arrays and lists? Can you explain how this is done in fluent? Regards Mohinder |
|
March 19, 2020, 11:28 |
|
#9 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 19, 2020, 11:42 |
Point Array and Cell Marking
|
#10 |
Senior Member
|
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.
__________________
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. |
|
March 21, 2020, 14:03 |
|
#11 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 21, 2020, 14:54 |
|
#12 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 22, 2020, 05:19 |
Debugging
|
#13 |
Senior Member
|
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.
__________________
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. |
|
March 22, 2020, 05:37 |
|
#14 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 =| |
|
March 22, 2020, 05:46 |
|
#15 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 22, 2020, 05:49 |
Message
|
#16 |
Senior Member
|
That means it is not even going beyond #if !RP_HOST, which is weird. Did you try this in Serial?
__________________
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. |
|
March 22, 2020, 05:51 |
Journal
|
#17 |
Senior Member
|
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.
__________________
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. |
|
March 22, 2020, 06:10 |
|
#18 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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 |
|
March 22, 2020, 06:43 |
Error
|
#19 |
Senior Member
|
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.
__________________
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. |
|
March 22, 2020, 06:57 |
|
#20 |
Member
Mohinder Suresh
Join Date: Dec 2014
Posts: 32
Rep Power: 11 |
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! |
|
|
|