-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Higher auto-refinement limits #285
base: master
Are you sure you want to change the base?
Conversation
auto_ref_max = 16; | ||
auto_ref_max_surf_elem = 20000; | ||
auto_ref_max = 32; | ||
auto_ref_max_surf_elem = 5000000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we have a need to increase auto_ref_max
-- 16 is more than sufficient for any practical case. For extreme cases it can be increased manually with the keys.
Also, I think increasing auto_ref_max_surf_elem
to 25x
from
Another option is to keep the current value and instead issue a warning in the terminal (we may want to add a feature where terminal messages are shown for a brief moment in the main window and then fade away) when the auto-selected refinement factor is less than the max of the orders of the mesh and the order of the field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what we want ideally is that these are set to the maximum values for what a "reasonable" mesh may need, and then for GLVis to select the actual auto-refinement values based on the order of the mesh (and solution).
For example auto_ref_max
should be at least max{ element_order, gf_order}
, maybe scaled by a factor of 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, maximum of some reasonable value and a value based on the grid function + mesh order 👍 , but it could be capped by some higher number maybe? To give the user a chance to change the value and not burn off the computer right away 🔥 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, "reasonable" auto-selected refinement factor is mainly driven by the time it takes to display the initial mesh. If possible, displaying the initial mesh should not take longer than ~0.1-0.3 sec on relatively new hardware. If we roughly say that the time to display some surface is proportional to to the point evaluations we need to perform, then we need to choose an upper bound for auto_ref_max_surf_elem
which gives the desired time limit. Of course, achieving this limit may not be possible when the number of the drawn surface elements is too big.
In the methods VisualizationSceneSolution::GetAutoRefineFactor()
and VisualizationSceneSolution3d::GetAutoRefineFactor()
, the number of point evaluations is computed as ne*(ref+1)*(ref+1)
where ne
is the number of surface elements in the mesh (i.e. number of elements in 2D meshes, embedded in 2D or 3D, or the number of boundary elements for 3D meshes). So the question is: how many point evaluations can we do in the allowed ~0.1-0.3 sec -- we can debate what exact value to aim for in this range. The evaluation speed per point will depend to some extend on the orders of the mesh and the field, so to make things more concrete, let's say we should measure the evaluation times for
Does this sound like a "reasonable" approach to determine the upper limit auto_ref_max_surf_elem
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regardless of how we do the auto-selection of refinement level, users will need to be aware that for big meshes they may not get any element sub-divisions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There could be if order_ref
will give a number lower than 20k, or no? 🤔 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order_ref
is just an initial value for ref
before the while
loop (when the if
is true). So if order_ref < 16 && ne*(order_ref+1)*(order_ref+1) <= 100000
, you will get more refinements than order_ref
and no less refinements than before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem, for me, with @tzanio's suggestion (even when the while
loop is moved after the if else
statement) is that it can result in big jumps in speed for small change in the input. For example, if ne*(order_ref+1)*(order_ref+1)
is close but less than 2M we get ref=order_ref
and if we increase ne
just a little to push ne*(order_ref+1)*(order_ref+1)
beyond 2M, then can immediately go down to ref=1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, like this, yes, in the modified version it would work, but I thought it is more logical to iterate to the same limiting number as in the criterion for order_ref
to keep continuity and not jump down, as you say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I was proposing would solve it (updated version to have the same numbers):
int ne = mesh->GetNE(), ref = 1;
int autoref_max = min(max(ne*(order_ref+1)*(order_ref+1), 100k), 2M)
while (ref < 16 && ne*(ref+1)*(ref+1) <= autoref_max) { ref++; }
(which implies ref==order_ref
if it is in the range and order_ref < 16
)
This is meant to address the issue where small meshes are curved but refined versions of them appear to lose the curvature in GLVis. See also this task in #284
The reasons for that behavior are the auto-refinement limits, which previously were:
auto_ref_max = 16
)auto_ref_max_surf_elem = 20000
)Both of these variables are set in
lib/vsdata.cpp
After considering several options, I suggest that we just increase those variables to 32 and 5M respectively.
These limits seems to work fine on modern hardware and the waiting time for large meshes is a few seconds on my Mac.
@psocratis and @dylan-copeland -- do you mind trying this on your use cases and reporting if it works well?