Skip to content
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

Do not solve advection system if RHS is zero #898

Merged
merged 1 commit into from Jun 3, 2016

Conversation

jdannberg
Copy link
Contributor

Right now if the matrix and the right-hand side are zero (for example for the temperature advection), we get a floating point exception in the advection preconditioner that is not really helpful to figure out what the problem is. In addition, if there is a problem that does not need the temperature, but needs compositional fields, or it has a non-zero temperature/composition only from a given time step on, then we do not really want to solve the advection system in the time steps before.
This pull request changes the solver schemes, so that in case of a zero RHS we do not solve for the advection field, but just set it to zero everywhere.

@tjhei
Copy link
Member

tjhei commented May 28, 2016

👍

I just realized we can use system_matrix.block(bla,bla).linfty_norm() < eps to see if the matrix is all-zero. I guess we should add an AssertThrow inside the "else" that checks this before setting up the preconditioner. This would handle the case that the RHS is non-zero but the matrix is. Right now this would still blow up somewhere deep inside the preconditioner setup. Of course this doesn't cover the case that the RHS is non-zero and the matrix is non-zero but singular.

build_advection_preconditioner(AdvectionField::temperature(),
T_preconditioner);
solve_advection(AdvectionField::temperature());
if (system_rhs.block(AdvectionField::temperature().block_index(introspection)).l2_norm() <= std::numeric_limits<double>::min())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just compare to numeric zero, for two reasons.

First, x <= numeric_limits::min() is true if either x==numeric_limits::min() (which is a floating point comparison for equality that is unlikely to ever be true), or if x==0. The definition of numeric_limit::min() is so that the condition x < numeric_limit::min() is never true.

Second, rhs.l2_norm() has physical units, whereas numeric_limits::min() does not, and so a comparison cannot be correct without a scaling factor.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not quite correct (there is -0.0 and denormalized values that I catch this way), see http://cpp.sh/2nbma for example.

Second, rhs.l2_norm() has physical units,

Yes, we should probably do something like 1e-16*something_sensible_with_sensible_units, but I am not confident how to do this robustly so we went for the easy option.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in which cases do you think you could get -0.0 or a denorm out of the l2 norm? I think that's an academic consideration. Just compare against zero and be done with it. That's exactly the case you wanted to catch after all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure it is needed, but with your suggestion I get

a.cc: In function ‘int main()’:
a.cc:14:26: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
   std::cout << "" << (a==0.0);

with g++ 6.1. Any suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Baa, what a stupid warning! Comparing against 0 should definitely be safe.

I guess in that case leave it as it is, and add a comment to the effect that we really just want to compare against zero but can't because of the warning...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I added the comment, and after I noticed that I would have to add it in about 20 places, I moved all my new additions into solve_advection so that we do not have to duplicate the code.

@bangerth
Copy link
Contributor

Nice improvement. There are lots of failing tests right now. I can't seem to connect to @tjhei 's tester at the moment, so can't say what's going on, but I suspect that for lots of tests the check triggers. Can you update the test outputs?

@bangerth
Copy link
Contributor

@tjhei -- what are the circumstances where the matrix is zero? This would make no sense in a time stepping scheme...

@jdannberg
Copy link
Contributor Author

Yes, exactly, but right now if the matrix is zero and the RHS is nonzero, we trigger some error in the advection preconditioner, and it would take the user some time to figure out what's going on. So we thought, maybe we could just add an assert and tell the user, hey, your matrix is zero, and you probably don't want to do that.

@bangerth
Copy link
Contributor

Yes, I agree that the assertion is a good idea. I just can't come up with any scenario in which the matrix would be zero. (Though there are now many more possibilities to screw up with the new assembler structure.)

@jdannberg
Copy link
Contributor Author

So we thought if c_p, thermal conductivity, and the entropy viscosity stabilization are zero, the matrix will be zero. (I am not really sure in which cases exactly the entropy viscosity stabilization is zero, maybe when the field itself is zero, but I had a model where the matrix was the problem, and I got a not very useful exception in the advection preconditioner.) There are terms on the RHS that are independent of that (e.g. the radiogenic heating), so we could end up with a zero matrix and a nonzero RHS.
If both are zero, it's fine, and we just don't solve the equation, but if the matrix is zero and the RHS is not, we throw an exception.

@tjhei
Copy link
Member

tjhei commented May 30, 2016

I can't seem to connect to @tjhei 's tester at the moment

Clemson had a planned power outage this weekend (yes, seriously). Should be back to normal later today.

@jdannberg jdannberg force-pushed the zero_RHS branch 3 times, most recently from 1d70fc2 to 1104082 Compare May 30, 2016 12:45
@bangerth
Copy link
Contributor

I see. Yes, if c_p is zero, then you might get a zero matrix. As I said, the assertion certainly doesn't hurt.

@jdannberg jdannberg force-pushed the zero_RHS branch 3 times, most recently from 44e7057 to 884f8ce Compare June 2, 2016 12:58
@bangerth
Copy link
Contributor

bangerth commented Jun 3, 2016

This looks good to me.

@tjhei -- there is a failure with this test here: http://www.math.clemson.edu/~heister/cib/aspect-8.4.1/cc22a221934bec4c0d561d798af347162a9d0c94/changes-clang.diff
This is because the error message on clang is different than the one stored in the output file for gcc, for the case of a test that is supposed to fail. Ideas?

@bangerth bangerth merged commit 7b040e4 into geodynamics:master Jun 3, 2016
@tjhei
Copy link
Member

tjhei commented Jun 4, 2016

This is because the error message on clang is different than the one stored in the output file for gcc, for the case of a test that is supposed to fail. Ideas?

I was going to fix this together with Juliane later today. I think it is a very bad idea merging pullrequests that do not pass all tests.

@bangerth
Copy link
Contributor

bangerth commented Jun 5, 2016

Yes, my bad. I had looked at the error message, found it unrelated to the current patch, and decided that we can handle these errors in patch review. I knew you were eventually going to fix this, but you're right that I could also just have waited for that to happen.

@tjhei
Copy link
Member

tjhei commented Jun 6, 2016

Yes, my bad.

No problem. I guess as long as we try to keep up with failing tests, we will be fine. ;-)

@jdannberg jdannberg deleted the zero_RHS branch May 8, 2017 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants