-
Notifications
You must be signed in to change notification settings - Fork 113
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
Taal: Hyperbolic diffusion and AMR controller #227
Conversation
Codecov Report
@@ Coverage Diff @@
## dev #227 +/- ##
==========================================
+ Coverage 89.52% 89.59% +0.06%
==========================================
Files 58 60 +2
Lines 10438 10485 +47
==========================================
+ Hits 9345 9394 +49
+ Misses 1093 1091 -2
Continue to review full report at Codecov.
|
resid_tol = 5.0e-12 # TODO: Taal, move this parameter to the callback | ||
equations = HyperbolicDiffusionEquations2D(resid_tol) | ||
|
||
initial_conditions = Trixi.initial_conditions_harmonic_nonperiodic |
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 noticed that sometimes we use, e.g., initial_conditions = Trixi.intial_conditions_harmonic_nonperiodic
whereas in my elixir conversions I simply used, e.g., initial_conditions = initial_conditions_rotor
. Is this a matter of convention or should I edit my elixir files to do it like this?
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 you did is perfectly fine. We need to decide which boundary conditions to keep in Trixi, see #207. If you have some time, it would be nice if you can note your thoughts on this there.
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.
That's marked as a blocking issue before we merge Taal (#200) into master
.
equations = HyperbolicDiffusionEquations2D(resid_tol) | ||
|
||
initial_conditions = Trixi.initial_conditions_poisson_nonperiodic | ||
boundary_conditions = (Trixi.boundary_conditions_poisson_nonperiodic, |
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 forget, is there a schematic anywhere of which entry of the four component array corresponds to "bottom" "top" "left" or "right"? This could be useful documentation for new users, or me for that matter :)
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.
Good point! We use the usual numbering of the direction
s, i.e. 1 => -x, 2 => +x, 3 => -y, 4 => +y
. I've added a comment here and started to documents some of these conventions in d8f7b06
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.
Overall very nice! I left two comments for clarification in the new hyperbolic diffusion elixir files, but I think this is good to go.
For the multiphysics runs, should the euler + gravity also use the SteadyStateCallback
or does it detect steady state another way?
We don't need the |
Memo: Merge #223 into |
Ah gotcha. I forgot that the callback structure is for the ODE package and not the in-house integrators |
condition = (u, t, integrator) -> alive_interval > 0 && ((integrator.iter % alive_interval == 0 && (analysis_interval == 0 || integrator.iter % analysis_interval != 0)) || t == integrator.sol.prob.tspan[2]) | ||
condition = (u, t, integrator) -> alive_interval > 0 && ( | ||
(integrator.iter % alive_interval == 0 && (analysis_interval == 0 || integrator.iter % analysis_interval != 0)) || | ||
t == integrator.sol.prob.tspan[2] || isempty(integrator.opts.tstops)) |
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 does isempty(integrator.opts.tstops)
check for? Is this non-empty if another callback marked this as the last time step and that the solver finishes afterwards?
IndicatorThreeLevel(semi, indicator; base_level=1, | ||
med_level=base_level, med_threshold=0.0, | ||
max_level=base_level, max_threshold=1.0) | ||
ControllerThreeLevel(semi, indicator; base_level=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.
TBH, I do not like the name Controller
here, as it gives no indication of what is being controlled. I have a similar beef with Indicator
, but since that's used for multiple purposes, I was not able to come up with a better name. However, here I'd suggest to call the AMR Controllers AmrController
(or AMRController
). What do you think @ranocha?
@@ -337,6 +339,7 @@ function (cb::DiscreteCallback{Condition,Affect!})(sol::ODESolution) where {Cond | |||
@unpack analyzer = analysis_callback | |||
|
|||
l2_error, linf_error = calc_error_norms(sol.u[end], sol.t[end], analyzer, semi) | |||
(; l2=l2_error, linf=linf_error) |
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.
Shouldn't this be
return (l2=l2_error, linf=linf_error)
?
reltol::RealT | ||
end | ||
|
||
function SteadyStateCallback(; abstol=1.0e-8, reltol=1.0e-6) |
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.
Are we sure that default tolerances make sense here? I am really asking, maybe they do, but intuitively I would say that this is so application dependent it does not make much sense (and that instead we should force the users to pick values.
# But that would remove the simplest possibility to write that stuff to a file... | ||
# We could of course implement some additional logic and workarounds, but is it worth the effort? | ||
function (indicator::IndicatorThreeLevel)(u::AbstractArray{<:Any}, | ||
mesh::TreeMesh, equations, dg::DG, cache) | ||
function (controller::ControllerThreeLevel)(u::AbstractArray{<:Any}, |
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 wonder if it is really necessary here to make this a callable instead of a free function (I've left a similar comment elsewhere). We don't have to discuss it here (I'll put it on the next meeting agenda), but maybe for this specific case there's a strong rationale?
I've added a new
SteadyStateCallback
(with optional absolute and relative tolerances). Moreover, I've renamed theIndicatorThreeLevel
toControllerThreeLevel
as suggested by @gregorgassner in #219.