-
Notifications
You must be signed in to change notification settings - Fork 92
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
Test coverage for PointEval with nonlinear geometries #820
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #820 +/- ##
==========================================
+ Coverage 93.58% 93.67% +0.08%
==========================================
Files 39 39
Lines 5895 5990 +95
==========================================
+ Hits 5517 5611 +94
- Misses 378 379 +1 ☔ View full report in Codecov by Sentry. |
I moved the computation of J and x without the caches (i.e. GeometryMapping) into GeometryMapping.jl and common_values.jl and changed the signature for the PointEvalHandler to support also mixed-dimensional grids (which are e.g. obtained by mixing shells, beams and solid elements in one grid). These functions are up to further optimization in subsequent PRs (i.e. the stuff which I do in the GPU support PR). I also fixed an oopsie in the line searcher (which we need to identify the cell boundary for nonlinear cells). Docs have been added as suggested. |
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.
Nice work - really cool with the ever-increasing support for embedded elements!
-
I would suggest leaving the inclusion of
sample_random_point
intosrc
to a separate pr for now. -
I like the renaming of
x
tocell_coordinates
, but on the other hand such a renaming is unrelated? If renamed it should probably also be renamed in thereinit!
methods? Should this renaming take place in a separate pr then?
I'm unsure regarding iterations for embedded elements. I would have thought we should find the value of
I suppose the pinv
updates are then doing this in some quasi-newton fashion? (But last time I checked, this is quite slow, so probably the above algorithm is faster even with the higher order derivative calculations?)
But since we are using autodiff anyway to compute the gradients of hessians of the base functions, perhaps it would be equally efficient to just define the residual function and just iterate on this? I.e.
function residual(ξ::Vec{dim}, x0::Vec{dim}, ip, cell_coordinates::AbstractVector{<:Vec{dim}) where dim
return spatial_coordinate(ip, ξ, cell_coordinates) - x0
end
function residual(ξ::Vec{dim}, x0::Vec{dim}, ip, cell_coordinates::AbstractVector{<:Vec{dim}) where dim
dxdξ, x = gradient(ξ_ -> spatial_coordinate(ip, ξ_, cell_coordinates), :all)
# do scaling if desired or needed?
return (x - x0) \cdot dxdξ
end
(And even if not used this modified residual, I suppose the first definition of residual can be used to remove the need for the calculate_mapping_and_spatial_coordinate
functions?
Thanks for taking the time @KnutAM and @fredrikekre !
I am not a big fan of making many small 1-5 line PRs (i.e. add docs, move function with same name from one file to another, ..) due to the associated overhead and dependencies, but I can make many tiny PRs if it is preferred.
My initial idea was also to have better modularity for the inner solver, but I could not find a good way how to do it. The rationale behind the current Newton solver for embedded (nonlinear) stuff is that it does not converge to a root if the coordinate is not in the element. You can interpret the solution of the linear system in a least square sense, as pinv returns by default the Moore-Penrose pseudoinverse. The problem with the projection is that you need additional infrastructure to handle the projections properly. Both approaches are valid tho.
I am not sure if I follow the idea here. So you are proposing to use a gradient descend over a Newton with line search as default? I think this will end up with the same issues as master for points near (or even on) element boundaries. |
I rather prefer the opposite, when one PR does one thing (of course - introducing a new feature should also include updated docs and test) and refactoring is left as a standalone pr as this makes the review easier. Furthermore, some changes such as the change from The reason for suggesting to wait with the inclusion of the testing functions was simply because I think a utils package or including these functions in core is worthwhile discussing, and would be bad to have that discussion stopping this pr.
No, rather the opposite - the current implementation is a quasi-newton for embedded elements due to the pseudo-inverse. With that code the regular elements would have no change in algorithm, but with easy extension to the embedded elements (but there, it is not guaranteed that the problem is convex / has a solution, not sure if the pseudo inverse approach can circumvent this). I'm struggling with makie-issues, so to take a quick break I'll add a PR to this branch showing what I meant (and check if it actually works :)) (Edit: #876) |
53e919d
to
8b93b9b
Compare
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.
Long time since I looked at this (sorry!)
I think it would be good to move some unrelated changes to a separate PR, that will also keep the git blames easier to follow.
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.
A few more comments, but otherwise lgtm!
61b6b3b
to
3668dc6
Compare
# set up tree structure for finding nearest nodes to points | ||
kdtree = KDTree(reinterpret(Vec{dim,T}, getnodes(grid))) | ||
nearest_nodes, _ = knn(kdtree, points, search_nneighbors, true) | ||
|
||
cells = Vector{Union{Nothing, Int}}(nothing, length(points)) | ||
local_coords = Vector{Union{Nothing, Vec{dim, T}}}(nothing, length(points)) | ||
local_coords = Vector{Union{Nothing, Vec{1, T},Vec{2, T},Vec{3, T}}}(nothing, length(points)) |
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 is the reason for this change?
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.
Support for mixed-dimensional meshes. E.g. shells with beams.
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.
Okay, and if there is a field that lives on both domains then?
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 am not sure if I understand the question correctly. The point finder just gives you the reference coordinate and cell index for some spatial coordinate. If you have some spatial coordinate which lives on the boundary of two elements, then it is always up to the prayers of convergence which element is returned for now. Technically we need to distinguish this case from the case when the point is strictly in the interior of some element. But note that resolving this issue is orthogonal to the goal of this PR, which is about improving the handling of nonlinear geometries. Before this PR using either mixed-dimensional or embedded elements resulted in a cryptic error for users and it looks like changing this (and the solver to some pseudo-inverse instead of the actual inverse below) is sufficient to handle these cases. I can separate these 2 lines and the tests into a separate PR if you think it convolutes this PR too much
Point evaluation on master just does not work on nonlinear geometries. Here is an attempt to make it work. Fixes #763 but might not completely fix the point eval.
TODO
flexibility for inner solvernot sure how.Should be a separate PR.How is now included during review.