Large elements after adapt, but not requested
zhang-alvin opened this issue · 16 comments
I'm a new user to Omega_h and I'm seeing some larger than requested elements/edge lengths than what I believe I am requesting in the inputs.
I have this vertex field of desired sizes/edge-lengths shown below:
From which I derive a 2x2 matrix to pass in to Omega_h::MetricInput
:
which seems to have converted the values to a 1/h^2 form. Only the XX component of the tensor is shown.
After calling Omega_h::generate_metric
, I get the vertex field named metric
which is effectively identical to the previous image, but is now only a single component:
Calling Omega_h::adapt()
leads to:
which has several really large elements. I suspect that I'm setting up the inputs incorrectly, so I'm posting the calls I used:
Omega_h::MetricInput input;
input.sources.push_back(Omega_h::MetricSource{OMEGA_H_GIVEN, 1.0, "target_metric",OMEGA_H_ISO_SIZE,OMEGA_H_ABSOLUTE});
input.should_limit_gradation = false;
input.verbose=true;
Omega_h::generate_metric_tag(&om, input);
auto opts = Omega_h::AdaptOpts(&om);
opts.max_length_allowed = 1.5;
Omega_h::adapt(&om, opts);
I would turn gradation limiting back on. Those "large" elements are the result of last-resort edge collapses done to improve quality, and the only reason I can think of for the code to get so worried about quality is that the original size field is so spotty that locally one can get into high-gradation states.
Also, in addition to limiting, I would use approach_metric
instead of adapt
.
In particular:
Omega_h::MetricInput input;
input.sources.push_back(Omega_h::MetricSource{OMEGA_H_GIVEN, 1.0, "target_metric",OMEGA_H_ISO_SIZE,OMEGA_H_ABSOLUTE});
input.should_limit_gradation = true;
input.verbose=true;
Omega_h::generate_target_metric_tag(&om, input);
auto opts = Omega_h::AdaptOpts(&om);
Omega_h::approach_metric(&om, opts);
After thinking about it some more I think trying to do it all in one adapt could also be problematic.
Thanks @ibaned.
The sizes should already be graded in that no two edge-adjacent vertices should have sizes that have a ratio greater than 1.5. If I turn on the gradation limiting, is there a "good" value for the max gradation rate?
Turning on the gradation limiting gets me a new error:
limited gradation in 4 steps
generated metrics in 0.047728 seconds
maximum edge length 2.889738 > maximum allowed length 2.828427
signal 6 caught by pcu
Our grading algorithm is more advanced than that, and the gradation rate used in our algorithm should be close to 1.0
, although decreasing it to like 0.5
can sometimes also help.
Are you sure you're calling approach_metric
?
I see.
Yes I am sure I'm calling approach_metric
. Is there a way to increase the verbosity?
That error only shows if your original mesh doesn't match the original metric (metric
). If we're calling generate_target_metric_tag
, then the metric we're forming should be called target_metric
and shouldn't affect the original metric
. Is there something in the code to initialize the original metric
before adaptation starts?
Oh... its also dangerous I think to have the "given" field be also named target_metric
. We should probably name the input field something else besides metric
and target_metric
.
Indeed, changing the "given" field name to something else allows approach_metric
to successfully proceed!
Fantastic! Let me know if the mesh looks any better
Unfortunately, it doesn't seem like anything is happening to the mesh. Going back to your comment on the target_metric
and the metric
tags, do I need to explicitly define both prior to calling approach_metric
? Currently, I'm only calling generate_metric_tag
and not generate_target_metric_tag
.
//get the desired metric field
auto target_metrics = Omega_h::Write<Omega_h::Real>(om.nverts() * Omega_h::symm_ncomps(om.dim()));
auto sizeField = (&om)->get_array<Omega_h::Real>(Omega_h::VERT, "proteus_size");
auto f = OMEGA_H_LAMBDA(Omega_h::LO vert) {
//get value
auto sizeVal = Omega_h::get_vector<1>(sizeField,vert);
auto target_metric = Omega_h::compose_metric(
Omega_h::identity_matrix<2, 2>(), Omega_h::vector_2(sizeVal[0], sizeVal[0] ) );
Omega_h::set_vector(target_metrics, vert, Omega_h::symm2vector(target_metric));
};
Omega_h::parallel_for(om.nverts(), f);
om.add_tag(Omega_h::VERT, "initial_metric", Omega_h::symm_ncomps(om.dim()), Omega_h::Reals(target_metrics) );
//set up a metric field
Omega_h::MetricInput input;
input.sources.push_back(Omega_h::MetricSource{OMEGA_H_GIVEN, 1.0, "initial_metric",OMEGA_H_ISO_SIZE,OMEGA_H_ABSOLUTE});
input.should_limit_gradation = true;
input.verbose=true;
Omega_h::generate_metric_tag(&om, input);
auto opts = Omega_h::AdaptOpts(&om);
Omega_h::approach_metric(&om,opts);
Yes, you have to call generate_target_metric_tag
, because approach_metric
will move the mesh towards target_metric
. If you don't have anything else for the existing metric
, you can call add_implied_isos_tag
I called add_implied_isos_tag()
and now have a metric
field and a target_metric
field that look like what I should expect
Calling approach_metric
still isn't doing much. (before call is top with target_metric
, after call is bottom)
Does the metric
field need to be associated with the Omega_h::MetricInput
object in any way like what is needed with the target_metric
?
after the call to approach_metric
, the tag target_metric
should be gone and there should remain only the tag metric
. I'd confirm that before anything else. Also, in your "before" pictures, the values for target_metric
don't look that much bigger than metric
, its possible they are just not calling for much refinement yet.
So I think I misinterpreted the approach_metric
method. I took a look at one of the test cases, cylinder_adapt_test.cpp
and it uses the following call:
while (Omega_h::approach_metric(&om, opts)) Omega_h::adapt(&om, opts);
which if I use as well does lead to what I am requesting:
Desired mesh from initial post without the long edges/ large elements:
Which is to say, approach_metric
doesn't actually invoke mesh modification procedures?
Whoops, that's also my bad for forgetting about that, good catch!
I think that should resolve this issue. Thanks again for the help @ibaned.