Skip to content

Higher-order implicit Runge-Kutta methods for the partitioned heat equation#415

Merged
BenjaminRodenberg merged 40 commits intoprecice:developfrom
NiklasVin:bspline_interpolation
Jan 18, 2024
Merged

Higher-order implicit Runge-Kutta methods for the partitioned heat equation#415
BenjaminRodenberg merged 40 commits intoprecice:developfrom
NiklasVin:bspline_interpolation

Conversation

@NiklasVin
Copy link
Copy Markdown
Collaborator

With this implementation, you could compute the partitioned heat equation with any implicit RK method, which is provided
by ButcherTableaux.py file.
You just need to change the time stepping scheme tsm to the IRK you want to use.
The weak form is obtained algorithmically and does not need to be changed by the user.

NiklasVin and others added 30 commits October 20, 2023 20:08
Previously, there were cases, where an empty dictionary was returned by the function.
Additionally, runtime errors which occured when using single step methods are now fixed, as sub() was not defined for the Function space which is used for ssm
With the change, the function shouldn't get into trouble if it created a BSpline with a degree >3
Refactoring: Avoid special treatment for single stage
WIP: Import from FEniCS and simplify code.
The time of the i-th stage was computed incomprehensible. This was changed by just setting the time to t+c[i]*dt
Copy link
Copy Markdown
Contributor

@BenjaminRodenberg BenjaminRodenberg left a comment

Choose a reason for hiding this comment

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

Couldn't resist taking a look at the PR 😏 Generally looks good. I did not check the actual results, but this is something you are doing in much more detail than I can do it here. Therefore, I was mainly focusing on code style.

We should also try to directly move some minor changes to develop, but this is something I can do.

Comment on lines +39 to +40
import dolfin
from dolfin import FacetNormal, dot
from dolfin import FacetNormal, dot, project
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we use dolfin here? Let's stick to from fenics import .... I think FacetNormal is not needed, is it?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

project is provided by dolfin. And as the imports were already there, I used them.
Actually, also regarding the current implementation of heat.py, all imports from dolfin can be deleted, because dot is already imported above from fencis, and, as you said, FacetNormal is not used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But you can also use from fenics import project. I would suggest: Let's remove all dolfin imports here. We can then cherry-pick this change to develop, because you are of course right that it is not 100% the point of this PR to clean up the imports and therefore we should also not mix this up.

@BenjaminRodenberg
Copy link
Copy Markdown
Contributor

I just cleaned up the unnecessary dolfin imports via 71f8daa. Please merge develop into this PR to make the diff a bit more compact.

Copy link
Copy Markdown
Contributor

@BenjaminRodenberg BenjaminRodenberg left a comment

Choose a reason for hiding this comment

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

Minor readability comments. If this means that you have to start with all your testing from the beginning: You can also ignore these suggestions and we just apply this refactoring after this PR is merged.

Comment on lines +79 to +83
for i in range(num_stages):
uhelp = initial_condition
for j in range(num_stages):
uhelp = uhelp + tsm.A[i][j] * dt * ks[j]
u[i] = uhelp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
for i in range(num_stages):
uhelp = initial_condition
for j in range(num_stages):
uhelp = uhelp + tsm.A[i][j] * dt * ks[j]
u[i] = uhelp
for i in range(num_stages):
u[i] = initial_condition
for j in range(num_stages):
u[i] += tsm.A[i][j] * dt * ks[j]

Comment on lines +84 to +94
rh = 0
for i in range(num_stages):
rh = rh + f[i] * vs[i] * dx

# Assemble weak form from lhs and rhs
F = 0
for i in range(num_stages):
# cf. https://doi.org/10.1145/3466168 p.5 equation 14
F = F + weak_lhs(v=vs[i], u=u[i], k=ks[i])
F = F - rh
return F
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
rh = 0
for i in range(num_stages):
rh = rh + f[i] * vs[i] * dx
# Assemble weak form from lhs and rhs
F = 0
for i in range(num_stages):
# cf. https://doi.org/10.1145/3466168 p.5 equation 14
F = F + weak_lhs(v=vs[i], u=u[i], k=ks[i])
F = F - rh
return F
# Assemble weak form
F = 0
for i in range(num_stages):
# cf. https://doi.org/10.1145/3466168 p.5 equation 14
F += inner(ks[i], vs[i]) * dx + inner(grad(u[i]), grad(vs[i])) * dx - f[i] * vs[i] * dx
return F

I don't really see a good reason for introduction weak_lhs here. Currently, the whole script does not generalize that well, if you want to solve a different equation anyway, because the f comes from "the outside". But this is also ok here.

If you want to get rid of the index, you can also try:

for u, v, k, f in zip(us, vs, ks, fs):
    F += inner(k, v) * dx + inner(grad(u), grad(v)) * dx - f * v * dx

btw: Renaming the u from above to us and the f to fs I think would not harm. Currently, it's a bit odd that you say vs, but not us.

@BenjaminRodenberg
Copy link
Copy Markdown
Contributor

I think we should definitely try to get this merged into the tutorials, because it is an important test for waveforms in preCICE. But I'm still a bit unsure how we should continue here: For the sake of the review it was very useful to modify heat.py, but to me it is not clear whether we should still keep the simple version of the tutorial (without stages, just implicit Euler directly solving the system for u).

So there are the following three options:

  • Replace heat.py with the advanced high-order version. Drop the old and simple implicit Euler version.
  • Provide high-order as heat.py, but also keep a heatImplicitEuler.py in this folder.
  • Leave heat.py as it is, but provide heatHigherOrder.py in this folder.

Then, there is, of course, also the option to move this case into an entirely new folder tutorials/partitioned-heat-conduction-high-order, but I think this would not give this contribution the right level of attention.

Opinions @uekerman and @MakisH?

Comment on lines +26 to +27
The implementation of the higher-order implicit Runge-Kutta methods was mostly taken from:
https://github.com/NikoWul/FenicsIrksome
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FYI, the original repository has no license. I understand that @BenjaminRodenberg was related to (supervised?) that project, but it would be best to make this clear.

@MakisH
Copy link
Copy Markdown
Member

MakisH commented Jan 5, 2024

I think we should definitely try to get this merged into the tutorials, because it is an important test for waveforms in preCICE.

Definitely! No good work should see slow decay in unmerged PRs.

But I'm still a bit unsure how we should continue here: For the sake of the review it was very useful to modify heat.py, but to me it is not clear whether we should still keep the simple version of the tutorial (without stages, just implicit Euler directly solving the system for u).

My main argument here would be consistency: We have invested a lot of effort in having all solver options of each tutorial behave in similar ways and give similar results. By merging this as-is, it means that FEniCS will be doing something different than the rest of the solver options.

So there are the following three options:

* Replace `heat.py` with the advanced high-order version. Drop the old and simple implicit Euler version.

That would be the breaking case, so for me, this is a clear "no".

* Provide high-order as `heat.py`, but also keep a `heatImplicitEuler.py` in this folder.

This changes the default behavior, and hence the consistency with the rest, so also "no" for me.

* Leave `heat.py` as it is, but provide `heatHigherOrder.py` in this folder.

This sounds like the easiest, least intrusive option. How easy would it be to merge the two and make the implicit solver a special case, configurable at runtime? That could prevent some duplication.

Then, there is, of course, also the option to move this case into an entirely new folder tutorials/partitioned-heat-conduction-high-order, but I think this would not give this contribution the right level of attention.

We typically do this when we need a different precice-config.xml, which is not the case here. It would mainly lead to duplication.

My recommendation: Leave heat.py as-is, but provide the higher order solver as a special case (either in the same code or, if that is complicated, in a separate file).

…tation to a new file and reset heat.py to state of the dev branch
Copy link
Copy Markdown
Contributor

@BenjaminRodenberg BenjaminRodenberg left a comment

Choose a reason for hiding this comment

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

Looks good to me 👍 Will merge this now and apply some final changes directly on develop.

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.

3 participants