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

step-86: Use reasonable time stepping for a heat equation solver. #15540

Merged
merged 7 commits into from
Jul 18, 2024

Conversation

bangerth
Copy link
Member

step-26 uses a home-grown implicit Euler time stepper. We should really show how one can do that better, using the PETSc TS or SUNDIALS ARKode wrappers.

The current state of the PR is just a shell, but I wanted to open the PR to facilitate collaboration. Among the options I'd be open is to also replace step-52, which uses "better" time steppers, but nothing as sophisticated as the ones mentioned above. step-52 also has a number of known problems, see #7191 and #9684. Replacing step-52 is something I'll have to discuss with @Rombur tonight or tomorrow.

@stefanozampini FYI.

@bangerth bangerth mentioned this pull request Jun 30, 2023
14 tasks
@bangerth bangerth changed the title Create the framework for step-86. step-86: Use reasonable time stepping for a heat equation solver. Jun 30, 2023
@tamiko tamiko added this to the Developer workshop 2023 milestone Jul 1, 2023
@stefanozampini
Copy link
Contributor

@bangerth
Copy link
Member Author

bangerth commented Jul 2, 2023

Status for the night: I got step-26 converted to PETSc vectors and run (which requires #15577), but something is not right with hanging nodes. I'll get back to it tomorrow.

@stefanozampini
Copy link
Contributor

Status for the night: I got step-26 converted to PETSc vectors and run (which requires #15577), but something is not right with hanging nodes. I'll get back to it tomorrow.

I cannot see the code for step 26. Did you forget to push?

@bangerth
Copy link
Member Author

bangerth commented Jul 2, 2023

@stefanozampini I misspoke. The code is in the step-86 directory (which is currently the PETSc version of step-26).

@bangerth
Copy link
Member Author

bangerth commented Jul 2, 2023

The hanging node issue is because I commented out the line constraints.condense(system_matrix, system_rhs);. It doesn't compile with PETSc. I'll have to figure out why.

@bangerth
Copy link
Member Author

bangerth commented Jul 2, 2023

@stefanozampini I'm looking through the documentation. For SUNDIALS' ARKode, see https://dealii.org/developer/doxygen/deal.II/classSUNDIALS_1_1ARKode.html, the documentation presents the ODE to be solved with a mass matrix M as we typically have with PDEs. The documentation of PETScWrappers::TimeStepper does not have the mass matrix in the formulation it solves. What is the way users should handle this?

@stefanozampini
Copy link
Contributor

@stefanozampini I'm looking through the documentation. For SUNDIALS' ARKode, see https://dealii.org/developer/doxygen/deal.II/classSUNDIALS_1_1ARKode.html, the documentation presents the ODE to be solved with a mass matrix M as we typically have with PDEs. The documentation of PETScWrappers::TimeStepper does not have the mass matrix in the formulation it solves. What is the way users should handle this?

Petsc ts does not know anything about the mass matrix. Everything is implemented in terms of implicit residual and implicit jacobian, as per the documentation I wrote for deal.ii. see e.g here https://github.com/stefanozampini/petscopt/blob/73e4f9d50b1d216ff21d9322b5f83e8ca247ec24/src/mfemopt/modelproblems.cpp#L367 for an example using mfem

@stefanozampini
Copy link
Contributor

stefanozampini commented Jul 2, 2023

The implicit form of the ode is of the form F(t,x,xdot) = 0. TS expects the user to implement F and its "jacobian" : shift * dF/dxdot + dF/dx. dF/dxdot in single field FEM simulations is usually the mass matrix. Shift is a scalar that depends on the specific integrator

@bangerth
Copy link
Member Author

bangerth commented Jul 2, 2023

Ah, ok. Thanks for pointing me in the right direction!

@tamiko tamiko marked this pull request as draft July 3, 2023 21:03
@bangerth
Copy link
Member Author

bangerth commented Jul 4, 2023

@stefanozampini I didn't get to this today, and am traveling for the next 3 days. I did write most of the introduction. I'll eventually get around to finishing it sometime soon I hope.

@stefanozampini
Copy link
Contributor

@stefanozampini I didn't get to this today, and am traveling for the next 3 days. I did write most of the introduction. I'll eventually get around to finishing it sometime soon I hope.

@bangerth We (with @luca-heltai ) can continue on this in the next days if you are ok

@tamiko tamiko removed the WIP ⚠️ label Jul 4, 2023
@bangerth
Copy link
Member Author

bangerth commented Jul 4, 2023

@stefanozampini Absolutely. I would love that. I'm out for the moment, please go ahead!

@luca-heltai
Copy link
Member

luca-heltai commented Jul 8, 2023

@stefanozampini , @bangerth my stab at using the TimeStepper class (I tried pushing here, but github did not allow me to).

bangerth#18

@luca-heltai
Copy link
Member

luca-heltai commented Jul 10, 2023

@stefanozampini, this is how it should look like for both in-homogeneous BC, and time dependent rhs. Unfortunately, I can't seem to make the boundary conditions work, and I suspect it is related to the fact that we are missing the correct right hand side when we solve the system.

The main difference is that the system is solved by TS (actually by SNES), not by deal.II, and we have no control over what is passed to the solve routine. In particular, essential boundary conditions for linear problems result in a rhs term (that we discussed extensively), but I have nowhere I can tell PETSc that when this should happen (except perhaps when assembling the residual, but that's not right, since the system that is solved by the nonlinear solver is not solving for a solution, but for an update w.r.t. to the solution (i.e., it should have zero BC).

Anyway, I'm a bit confused of what is the right way forward. In this implementation, I think I have essentially copied what you have in MFEM, but there must be some subtle detail that I got wrong.

I think this is now solved, but not in the way I wanted. Using constraints twice to set time dependent boundary conditions and modify only the inhomogeneity without clearing and resetting the constraints does not seem to be possible at the moment.

@luca-heltai
Copy link
Member

heat

With last commit, one obtaines the movie above. This is now ok, but I discovered something (a bug? a feature?) that took some time for me to understand.
When calling VectorTools::interpolate_boundary_values with constraints as argument, if the constraints are already closed, the function call does nothing (it does not throw, but it does not set the in-homogeneous constraints either).

@luca-heltai
Copy link
Member

Ok, we now have

./step-86 -snes_test_jacobian                                                  ✹ ✭step-86 

===========================================
Number of active cells: 75
Number of degrees of freedom: 100

Time step 0 at t=0
    ---------- Testing Jacobian -------------
    Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference
      of hand-coded and finite difference Jacobian entries greater than <threshold>.
    Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is
      O(1.e-8), the hand-coded Jacobian is probably correct.
    ||J - Jfd||_F/||J||_F = 5.3439e-10, ||J - Jfd||_F = 1.41426e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.24459e-10, ||J - Jfd||_F = 5.94028e-09
Time step 1 at t=0.025
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.95192e-10, ||J - Jfd||_F = 7.81221e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.20126e-10, ||J - Jfd||_F = 3.1791e-09
Time step 2 at t=0.05
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.0985e-10, ||J - Jfd||_F = 5.55366e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.24247e-10, ||J - Jfd||_F = 3.28817e-09
Time step 3 at t=0.075
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.55447e-10, ||J - Jfd||_F = 1.20533e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.5967e-10, ||J - Jfd||_F = 6.87214e-09
Time step 4 at t=0.1
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.04795e-10, ||J - Jfd||_F = 8.06635e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.81942e-10, ||J - Jfd||_F = 7.46157e-09
Time step 5 at t=0.125
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.76214e-10, ||J - Jfd||_F = 9.95645e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.38844e-10, ||J - Jfd||_F = 6.32098e-09
Time step 6 at t=0.15
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.8384e-10, ||J - Jfd||_F = 7.51178e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.50165e-10, ||J - Jfd||_F = 6.62057e-09
Time step 7 at t=0.175
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.34937e-10, ||J - Jfd||_F = 6.21757e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.41958e-10, ||J - Jfd||_F = 6.40339e-09
Time step 8 at t=0.2
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 5.67647e-10, ||J - Jfd||_F = 1.50227e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.41692e-10, ||J - Jfd||_F = 9.04282e-09
Time step 9 at t=0.225
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.16992e-10, ||J - Jfd||_F = 8.38914e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.07713e-10, ||J - Jfd||_F = 8.14357e-09
Time step 10 at t=0.25
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.63221e-10, ||J - Jfd||_F = 6.96612e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.91467e-10, ||J - Jfd||_F = 7.71364e-09
Time step 11 at t=0.275
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.76322e-10, ||J - Jfd||_F = 7.31282e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.62869e-10, ||J - Jfd||_F = 6.95678e-09
Time step 12 at t=0.3
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.80995e-10, ||J - Jfd||_F = 1.0083e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.42137e-10, ||J - Jfd||_F = 9.05461e-09
Time step 13 at t=0.325
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.12022e-10, ||J - Jfd||_F = 8.25763e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.8661e-10, ||J - Jfd||_F = 7.58508e-09
Time step 14 at t=0.35
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.44872e-10, ||J - Jfd||_F = 6.4805e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.504e-10, ||J - Jfd||_F = 6.6268e-09
Time step 15 at t=0.375
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.15072e-10, ||J - Jfd||_F = 1.09848e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.17883e-10, ||J - Jfd||_F = 8.41272e-09
Time step 16 at t=0.4
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.09515e-10, ||J - Jfd||_F = 8.19127e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.6425e-10, ||J - Jfd||_F = 6.99335e-09
Time step 17 at t=0.425
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.70022e-10, ||J - Jfd||_F = 9.79258e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.82082e-10, ||J - Jfd||_F = 7.46525e-09
Time step 18 at t=0.45
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.3024e-10, ||J - Jfd||_F = 6.09326e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.26588e-10, ||J - Jfd||_F = 3.35013e-09
Time step 19 at t=0.475
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.80427e-10, ||J - Jfd||_F = 1.27144e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.04768e-10, ||J - Jfd||_F = 8.06563e-09
Time step 20 at t=0.5
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.92672e-10, ||J - Jfd||_F = 7.74553e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.59937e-10, ||J - Jfd||_F = 6.87919e-09
Time step 21 at t=0.525
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.09541e-10, ||J - Jfd||_F = 8.19197e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.72016e-10, ||J - Jfd||_F = 4.55238e-09
Time step 22 at t=0.55
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.45577e-10, ||J - Jfd||_F = 6.49916e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.67505e-10, ||J - Jfd||_F = 4.43299e-09
Time step 23 at t=0.575
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.70851e-10, ||J - Jfd||_F = 1.2461e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.13483e-10, ||J - Jfd||_F = 8.29627e-09
Time step 24 at t=0.6
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.35526e-10, ||J - Jfd||_F = 8.87965e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.13293e-10, ||J - Jfd||_F = 8.29126e-09
Time step 25 at t=0.625
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.5879e-10, ||J - Jfd||_F = 9.49533e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.65781e-10, ||J - Jfd||_F = 7.03386e-09
Time step 26 at t=0.65
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.90174e-10, ||J - Jfd||_F = 7.67941e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.93313e-10, ||J - Jfd||_F = 7.76249e-09
Time step 27 at t=0.675
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.209e-10, ||J - Jfd||_F = 1.11391e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.98862e-10, ||J - Jfd||_F = 1.05558e-08
Time step 28 at t=0.7
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.75041e-10, ||J - Jfd||_F = 9.9254e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.38481e-10, ||J - Jfd||_F = 1.16043e-08
Time step 29 at t=0.725
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 5.09845e-10, ||J - Jfd||_F = 1.3493e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.08349e-10, ||J - Jfd||_F = 8.16041e-09
Time step 30 at t=0.75
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.53085e-10, ||J - Jfd||_F = 9.34434e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.22962e-10, ||J - Jfd||_F = 8.54715e-09
Time step 31 at t=0.775
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.75264e-10, ||J - Jfd||_F = 9.93131e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.8732e-10, ||J - Jfd||_F = 7.60389e-09
Time step 32 at t=0.8
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.42054e-10, ||J - Jfd||_F = 9.0524e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.11717e-10, ||J - Jfd||_F = 1.0896e-08
Time step 33 at t=0.825
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.27218e-10, ||J - Jfd||_F = 1.13063e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.98193e-10, ||J - Jfd||_F = 7.89164e-09
Time step 34 at t=0.85
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.85412e-10, ||J - Jfd||_F = 7.55338e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.43736e-10, ||J - Jfd||_F = 6.45043e-09
Time step 35 at t=0.875
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 5.02984e-10, ||J - Jfd||_F = 1.33114e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 3.08755e-10, ||J - Jfd||_F = 8.17117e-09
Time step 36 at t=0.9
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.74383e-10, ||J - Jfd||_F = 7.26151e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 4.36448e-10, ||J - Jfd||_F = 1.15505e-08
Time step 37 at t=0.925
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 5.15677e-10, ||J - Jfd||_F = 1.36473e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.36557e-10, ||J - Jfd||_F = 6.26044e-09
Time step 38 at t=0.95
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.16914e-10, ||J - Jfd||_F = 5.74061e-09
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 1.41909e-10, ||J - Jfd||_F = 3.75561e-09
Time step 39 at t=0.975
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 5.22855e-10, ||J - Jfd||_F = 1.38373e-08
    ---------- Testing Jacobian -------------
    ||J - Jfd||_F/||J||_F = 2.77547e-10, ||J - Jfd||_F = 7.34525e-09
Time step 40 at t=1

@luca-heltai
Copy link
Member

I'll make it work in parallel later tonight.

@@ -90,7 +90,8 @@ namespace Step86
DoFHandler<dim> dof_handler;
IndexSet hanging_nodes;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can remove this now

@stefanozampini
Copy link
Contributor

I believe we are in quite good shape. @bangerth @luca-heltai Do you have any objection if I rebase against the later master and squash it into two commits? (One for TS changes, one for step-86). I think we have converged with the needed TS changes and I would like to open a separate PR for that. For step-86, I believe we only want to implement a MMS test and maybe make it nonlinear too.

@bangerth
Copy link
Member Author

Go ahead with the rebase!

As for nonlinear -- I'm ok with solving the same problem as in step-26 (+ having non-constant boundary values), but I then it might also be nice to make the problem more complicated by adding a nonlinearity. What do you have in mind?

@stefanozampini
Copy link
Contributor

I guess @luca-heltai was proposing Allen-Cahn

@bangerth
Copy link
Member Author

Video of the solution (not too exciting, but that's not the point) is here: https://www.youtube.com/watch?v=fhJVkcdRksM

@bangerth
Copy link
Member Author

/rebuild

Copy link
Contributor

@stefanozampini stefanozampini left a comment

Choose a reason for hiding this comment

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

I am proposing some editing but it looks quite good to me. Thanks @bangerth

do by oneself. In the current case, deal.II has interfaces to two
such libraries: SUNDIALS, the *SUite of Nonlinear and DIfferential/ALgebraic
equation Solvers* (and here specifically the Runge-Kutta-type solvers
wrapped in the SUNDIALS::ARKode class), and PETSc's TS sub-packaged
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
wrapped in the SUNDIALS::ARKode class), and PETSc's TS sub-packaged
wrapped in the SUNDIALS::ARKode class), and PETSc's TS sub-package

Comment on lines 155 to 157
On the other hand, when using the PETScWrappers::TimeStepper class that
wraps the PETSc TS sub-package, you will find that when stating things
as a typical ODE, it does not like the presence of a mass matrix. But
it can solve ODEs that are stated in "implicit" form, and in that
case we simply bring everything to the left hand side and obtain
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
On the other hand, when using the PETScWrappers::TimeStepper class that
wraps the PETSc TS sub-package, you will find that when stating things
as a typical ODE, it does not like the presence of a mass matrix. But
it can solve ODEs that are stated in "implicit" form, and in that
case we simply bring everything to the left hand side and obtain
On the other hand, when using the PETScWrappers::TimeStepper class,
we can solve ODEs that are stated in a general "implicit" form, and in that
case we simply bring everything to the left hand side and obtain

a small abuse of terminology. In the current case, this matrix
is $J=A + \alpha M$. If you have read through step-26, it is probably
not lost on you that this matrix appears prominently there as well --
with $\alpha$ being a multiple of the inverse of the time step $k_n$.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
with $\alpha$ being a multiple of the inverse of the time step $k_n$.
with $\alpha$ being a multiple of the inverse of the time step.

Comment on lines 219 to 222
- A callback that is called at the end of each time step (or perhaps
at other intervals) and that is provided with the current solution
and other information and that can be used to "monitor" the progress
of computations. One of the ways in which this can be used is to
output visualization data every few time steps.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- A callback that is called at the end of each time step (or perhaps
at other intervals) and that is provided with the current solution
and other information and that can be used to "monitor" the progress
of computations. One of the ways in which this can be used is to
output visualization data every few time steps.
- A callback that is called at the end of each time step
and that is provided with the current solution
and other information that can be used to "monitor" the progress
of computations. One of the ways in which this can be used is to
output visualization data every few time steps.

Comment on lines 270 to 271
the algebraic degrees of freedom are listed. At the end of each time
step (or perhaps also at other times), a second callback then needs to
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
the algebraic degrees of freedom are listed. At the end of each time
step (or perhaps also at other times), a second callback then needs to
the algebraic degrees of freedom are listed. At the end of each solution stage of the solver, a second callback then needs to

examples/step-86/step-86.cc Outdated Show resolved Hide resolved
PETScWrappers::PreconditionBoomerAMG preconditioner;
preconditioner.initialize(jacobian_matrix);
#else
PETScWrappers::PreconditionSSOR preconditioner;
Copy link
Contributor

Choose a reason for hiding this comment

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

PETSc has his native AMG ('-pc_type gamg'). It would make sense to use it here (but it is not wrapped), since SSOR is a bad choice. Missing deal.II interfaces to PETSc solvers is why I prefer command line options solvers. Once the optimal is found, then it makes sense to add a solve_with_jacobian callback

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, fair point. I augmented the comment in front of the function.

// not to refine is done in the lambda function that calls the current
// function.)
//
// Breaking things into a "mark cells" function and into a "execute mesh
Copy link
Contributor

Choose a reason for hiding this comment

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

This is because you are not considering the point of view of the solver, and you are not discussing the actual callback, the decide_for_coarsening_and_refinement. For me, it is natural to first take a decision, inform the solver about that, and then the solver can do what it needs to be done before performing the actual remesh + transfer

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking about why you structured it this way. I think the simplest way would have been if the decide_... function really only does that: Decide whether we want to do mesh refinement. Then the marking along with the actual refinement would happen in the second callback, which would also be natural (keep marking and refinement together). But I suspect that you didn't do it that way because you don't have the solution vector available in the second callback (you only have a whole bunch of vectors), and so the marking needs to happen in the first callback.

I don't know whether it would be possible to query the TS object for the current solution vector? If that were the case, we could provide that in the second callback.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is the relevant PETSc code https://gitlab.com/petsc/petsc/-/blob/main/src/ts/interface/ts.c?ref_type=heads#L3841. resizesetup runs the deal.ii decide callback (actually, I wrote this in PETSc to support this from deal.II). The solution vector is the first vector of the list when doing the transfer. It looked clean to me, but if you think a different approach would be cleaner, please change it.

examples/step-86/step-86.cc Outdated Show resolved Hide resolved
examples/step-86/step-86.cc Outdated Show resolved Hide resolved
@bangerth bangerth force-pushed the step-86 branch 2 times, most recently from c8f5385 to 5f74525 Compare June 30, 2024 23:24
@bangerth
Copy link
Member Author

Thanks for your feedback, @stefanozampini ! I've made the changes as requested, plus the individual comments.

@stefanozampini
Copy link
Contributor

stefanozampini commented Jul 1, 2024 via email

@bangerth
Copy link
Member Author

bangerth commented Jul 1, 2024

Ah, yes. This produces the following:

Time step 0 at t=0
    0 SNES Function norm 9.318412725888e+00 
     5 linear iterations.
    1 SNES Function norm 1.924180820050e-07 
     8 linear iterations.
    2 SNES Function norm 1.809835536215e-15 
Time step 1 at t=0.025
    0 SNES Function norm 1.247790476607e+00 
     6 linear iterations.
    1 SNES Function norm 2.844552687154e-09 
Time step 2 at t=0.05
    0 SNES Function norm 2.167499872402e+00 
     5 linear iterations.
    1 SNES Function norm 3.798817340529e-08 
     8 linear iterations.
    2 SNES Function norm 1.392310824792e-15 
Time step 3 at t=0.075
    0 SNES Function norm 2.803905113816e+00 
     6 linear iterations.
    1 SNES Function norm 5.181376428365e-09 
Time step 4 at t=0.1
    0 SNES Function norm 3.145916725436e+00 
     6 linear iterations.
    1 SNES Function norm 6.699473113724e-09 
Time step 5 at t=0.125
    0 SNES Function norm 3.175550694797e+00 
     6 linear iterations.
    1 SNES Function norm 7.413516532669e-09 
Time step 6 at t=0.15
    0 SNES Function norm 2.893674410155e+00 
     6 linear iterations.
    1 SNES Function norm 7.326933026019e-09 

This was useful information -- thank you for pointing to that command line flag! It is an interaction between the linear solver (which solves to an accuracy of 1e-8 * src.l2_norm()) and the nonlinear solver (which apparently requires 1e-9 accuracy. I can get it down to one iteration in all time steps by solving to 1e-12 * src.l2_norm(). Do you know where the 1e-9 tolerance is set? It is not the two parameters in Error control in the input file:

    subsection Error control
      set absolute error tolerance = -1
      set relative error tolerance = -1

which apparently pertain to the ODE error, not the nonlinear error.

@tamiko
Copy link
Member

tamiko commented Jul 17, 2024

@bangerth Would you mind to fix the doxygen issue?

@bangerth
Copy link
Member Author

OK, I've rebased this now and it's ready from my side.

@kronbichler kronbichler merged commit 93dea5d into dealii:master Jul 18, 2024
16 checks passed
@bangerth bangerth deleted the step-86 branch July 18, 2024 14:29
@bangerth
Copy link
Member Author

Oh yay! Thank you, @stefanozampini and @luca-heltai for your work on this program!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants