-
Notifications
You must be signed in to change notification settings - Fork 102
Hessians for embedded elements #1257
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
base: master
Are you sure you want to change the base?
Changes from all commits
0eeecd9
06ac744
53e0939
7edb56b
8737dd3
831fd7f
158cc2b
8011c2f
6f7fbbd
7260a95
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,3 +24,4 @@ docs/src/changelog.md | |
| LocalPreferences.toml | ||
| docs/LocalPreferences.toml | ||
| benchmark/tune.json | ||
| .vscode/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ end | |
|
|
||
| @inline getjacobian(mv::MappingValues{<:Union{AbstractTensor, SMatrix}}) = mv.J | ||
| @inline gethessian(mv::MappingValues{<:Any, <:AbstractTensor}) = mv.H | ||
| @inline gethessian(mv::MappingValues{<:SMatrix, <:SArray}) = mv.H | ||
|
|
||
|
|
||
| """ | ||
|
|
@@ -112,6 +113,12 @@ geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip | |
| @inline function otimes_helper(x::Vec{sdim}, dMdξ::Vec{rdim}) where {sdim, rdim} | ||
| return SMatrix{sdim, rdim}((x[i] * dMdξ[j] for i in 1:sdim, j in 1:rdim)...) | ||
| end | ||
|
|
||
| @inline otimes_helper(x::Vec{dim}, d2Mdξ2::Tensor{2, dim}) where {dim} = x ⊗ d2Mdξ2 | ||
| @inline function otimes_helper(x::Vec{sdim}, d2Mdξ2::Tensor{2, rdim}) where {sdim, rdim} | ||
| return SArray{Tuple{sdim, rdim, rdim}}((x[i] * d2Mdξ2[j, k] for i in 1:sdim, j in 1:rdim, k in 1:rdim)...) | ||
| end | ||
|
|
||
| # End of embedded hot-fixes | ||
|
|
||
| # For creating initial value | ||
|
|
@@ -124,6 +131,10 @@ end | |
| function otimes_returntype(#=typeof(x)=# ::Type{<:Vec{dim, Tx}}, #=typeof(d2Mdξ2)=# ::Type{<:Tensor{2, dim, TM}}) where {dim, Tx, TM} | ||
| return Tensor{3, dim, promote_type(Tx, TM)} | ||
| end | ||
| function otimes_returntype(::Type{<:Vec{sdim, Tx}}, #=typeof(d2Mdξ2)=# ::Type{<:Tensor{2, rdim, TM}}) where {sdim, rdim, Tx, TM} | ||
| return typeof(StaticArrays.@SArray zeros(promote_type(Tx, TM), sdim, rdim, rdim)) | ||
| end | ||
|
|
||
|
|
||
| @inline function calculate_mapping(::GeometryMapping{0}, q_point::Int, x::AbstractVector{<:Vec}) | ||
| return MappingValues(nothing, nothing) | ||
|
|
@@ -140,12 +151,13 @@ end | |
|
|
||
| @inline function calculate_mapping(geo_mapping::GeometryMapping{2}, q_point::Int, x::AbstractVector{<:Vec}) | ||
| J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) | ||
| sdim, rdim = size(J) | ||
| (rdim != sdim) && error("hessian for embedded elements not implemented (rdim=$rdim, sdim=$sdim)") | ||
| H = zero(otimes_returntype(eltype(x), eltype(geo_mapping.d2Mdξ2))) | ||
| @inbounds for j in 1:getngeobasefunctions(geo_mapping) | ||
| J += x[j] ⊗ geo_mapping.dMdξ[j, q_point] | ||
| H += x[j] ⊗ geo_mapping.d2Mdξ2[j, q_point] | ||
| J += otimes_helper(x[j], geo_mapping.dMdξ[j, q_point]) | ||
| H += otimes_helper(x[j], geo_mapping.d2Mdξ2[j, q_point]) | ||
|
|
||
| # J += x[j] ⊗ geo_mapping.dMdξ[j, q_point] | ||
| # H += x[j] ⊗ geo_mapping.d2Mdξ2[j, q_point] | ||
| end | ||
| return MappingValues(J, H) | ||
| end | ||
|
|
@@ -170,13 +182,16 @@ end | |
| @inline function calculate_mapping(gip::ScalarInterpolation, ξ::Vec{rdim, T}, x::AbstractVector{<:Vec{sdim}}, ::Val{2}) where {T, rdim, sdim} | ||
| n_basefuncs = getnbasefunctions(gip) | ||
| @boundscheck checkbounds(x, Base.OneTo(n_basefuncs)) | ||
| (rdim != sdim) && error("hessian for embedded elements not implemented (rdim=$rdim, sdim=$sdim)") | ||
| J = zero(otimes_returntype(Vec{sdim, T}, Vec{rdim, T})) | ||
| H = zero(otimes_returntype(eltype(x), typeof(J))) | ||
| @inbounds for j in 1:n_basefuncs | ||
| d2Mdξ2, dMdξ, _ = reference_shape_hessian_gradient_and_value(gip, ξ, j) | ||
| J += x[j] ⊗ dMdξ | ||
| H += x[j] ⊗ d2Mdξ2 | ||
|
|
||
| J += otimes_helper(x[j], dMdξ) | ||
| H += otimes_helper(x[j], d2Mdξ2) | ||
|
|
||
| # J += x[j] ⊗ dMdξ | ||
| # H += x[j] ⊗ d2Mdξ2 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where did the computation of the hessian go?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aha, I only added it in above. This code then might not be tested atm. Also, what is the difference between |
||
| end | ||
| return MappingValues(J, H) | ||
| end | ||
|
|
||
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 think this type of construction of SArrays is fine, but I dont know how efficiently the compiler can optimize it, maybe someone else can review this part :)
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.
You were right, there are a lot of calls in there.
This implementation takes 24 ns on my system, I found a better version which only takes about 2 ns