-
Notifications
You must be signed in to change notification settings - Fork 12
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
Generalize surface normal calc #539
base: main
Are you sure you want to change the base?
Generalize surface normal calc #539
Conversation
Conflicts: src/schemes/fluid/weakly_compressible_sph/system.jl
…vchb/TrixiParticles.jlOpen into generalize_surface_normal_calc
Conflicts: examples/fluid/dam_break_oil_film_2d.jl src/schemes/fluid/weakly_compressible_sph/state_equations.jl
initial_condition :: IC | ||
mass :: MA # Array{ELTYPE, 1} | ||
pressure :: P # Array{ELTYPE, 1} | ||
density_calculator :: DC | ||
state_equation :: SE | ||
smoothing_kernel :: K | ||
smoothing_length :: ELTYPE | ||
ideal_neighbor_count :: Int | ||
color :: Int |
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.
This is never used, is it? Same for EDAC.
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.
Yes it will be used in #584
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.
As always, please remove it from this PR and add it when it's actually used.
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.
Great unnecessary conflicts in 5 Branches...
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.
Rebasing should really eliminate all your problems.
|
||
# After computation, check that surface normals have been computed | ||
@test all(isfinite.(system.cache.surface_normal)) | ||
@test all(isfinite.(system.cache.neighbor_count)) |
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.
Isn't this zero by default? Shouldn't you then check that this is not zero anymore?
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.
The inside will stay at 0.0. though.
for i in surface_particles | ||
@test isapprox(computed_normals[:, i], expected_normals[:, i], atol=0.05) | ||
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.
for i in surface_particles | |
@test isapprox(computed_normals[:, i], expected_normals[:, i], atol=0.05) | |
end | |
@test isapprox(computed_normals, expected_normals, atol=0.05) |
The loop will generate a lot of tests.
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.
This doesn't work since the normals are not always exactly 0.0 on the inside.
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.
@test isapprox(computed_normals[:, surface_particles], expected_normals[:, surface_particles], atol=0.05)
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 also doesn't work
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.
Expression: isapprox(computed_normals[:, surface_particles], expected_normals[:, surface_particles], atol = 0.04)
Evaluated: isapprox([0.3480639311878508 -0.3480639311878508 … 0.34806393118785095 -0.3480639311878508; 0.9374707994418061 0.9374707994418061 … -0.937470799441806 -0.937470799441806], [0.31622776601683794 -0.31622776601683794 … 0.31622776601683794 -0.31622776601683794; 0.9486832980505138 0.9486832980505138 … -0.9486832980505138 -0.9486832980505138]; atol = 0.04)
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.
According to the docs of isapprox
:
The norm keyword defaults to abs for numeric (x,y) and to LinearAlgebra.norm for arrays (where an alternative norm choice is sometimes useful).
In the loop, you checked the Linf norm of the difference, here you check the L2 norm, which becomes larger with the size of the vector when the Linf norm stays the same:
julia> norm(ones(100_000) - zeros(100_000))
316.22776601683796
For isapprox
, this means:
julia> isapprox(ones(100_000), zeros(100_000), atol=300)
false
julia> isapprox(ones(100_000), zeros(100_000), atol=400)
true
julia> isapprox(ones(100_000), zeros(100_000), atol=1.0, norm=x -> norm(x, Inf))
true
julia> isapprox(ones(100_000), zeros(100_000), atol=0.9, norm=x -> norm(x, Inf))
false
# Optionally, check that normals for interior particles are zero | ||
# for i in setdiff(1:nparticles, surface_particles) | ||
# @test isapprox(norm(system.cache.surface_normal[:, i]), 0.0, atol=1e-4) | ||
# 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.
?
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.
This is also part of #584
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 thought I used it there but this is rather tricky... Even with the special conditions that are implemented in #584
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.
And with a larger tolerance? There should be some test to ensure the inner values are not completely random.
And there should not be a commented out test in here.
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.
The problem is that not only the outer layer has the surface normal set but this goes some layers deep so the only possiblity is to eliminate several of the outer layers.
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.
Than the inside is 0
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 happens between the surface and the inner layers where it's 0? Is this just a shorter normal then? Can you test that the normal either points in the correct direction or is almost zero?
…vchb/TrixiParticles.jlOpen into generalize_surface_normal_calc
for i in surface_particles | ||
@test isapprox(computed_normals[:, i], expected_normals[:, i], atol=0.05) | ||
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.
@test isapprox(computed_normals[:, surface_particles], expected_normals[:, surface_particles], atol=0.05)
@@ -1,7 +1,7 @@ | |||
name = "TrixiParticles" | |||
uuid = "66699cd8-9c01-4e9d-a059-b96c86d16b3a" | |||
authors = ["erik.faulhaber <44124897+efaulhaber@users.noreply.github.com>"] | |||
version = "0.2.4-dev" | |||
version = "0.2.4" |
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 it makes more sense to wait for #529 before we release.
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.
Depends on how long that still will take...
foreach_point_neighbor(system, neighbor_system, | ||
system_coords, neighbor_system_coords, | ||
nhs) do particle, neighbor, pos_diff, distance | ||
colorfield[neighbor] += smoothing_kernel(system, distance) | ||
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.
foreach_point_neighbor(system, neighbor_system, | |
system_coords, neighbor_system_coords, | |
nhs) do particle, neighbor, pos_diff, distance | |
colorfield[neighbor] += smoothing_kernel(system, distance) | |
end | |
foreach_point_neighbor(neighbor_system, system, | |
neighbor_system_coords, system_coords, | |
nhs) do particle, neighbor, pos_diff, distance | |
colorfield[particle] += smoothing_kernel(system, distance) | |
end |
Otherwise you will get race conditions on multiple threads.
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.
Doesn't work there will be no neighbors
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.
Selfnote: I still need to revert this since this has been only changed at the moment from #666 and up
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.
foreach_point_neighbor(neighbor_system, system, ..., particles=eachparticle(neighbor_system))
, or the loop will go over all moving particles, which are none for a boundary system.
if system.cache.neighbor_count[i] < threshold | ||
@test all(system.cache.surface_normal[:, i] .== 0.0) | ||
else | ||
# For the linear arrangement, surface normals may still be zero | ||
# Adjust the test to account for this possibility | ||
@test true | ||
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.
Can you please fix this here then?
@inline function surface_normal_method(system::FluidSystem) | ||
return system.surface_normal_method | ||
end | ||
|
||
@inline function surface_normal_method(system) | ||
return nothing | ||
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.
Never used.
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.
This is used in #584
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.
Then add it there.
function initialize_colorfield!(system, ::BoundaryModelDummyParticles, neighborhood_search) | ||
system_coords = system.coordinates | ||
(; smoothing_kernel, smoothing_length) = system.boundary_model | ||
|
||
foreach_point_neighbor(system, system, | ||
system_coords, system_coords, | ||
neighborhood_search, | ||
points=eachparticle(system)) do particle, neighbor, pos_diff, | ||
distance | ||
system.boundary_model.cache.colorfield_bnd[particle] += kernel(smoothing_kernel, | ||
distance, | ||
smoothing_length) | ||
system.boundary_model.cache.neighbor_count[particle] += 1 | ||
end | ||
return system | ||
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.
Please add a test.
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 have added a test but this test will change in all subsequent PRs
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 that is better than reducing coverage here and potentially forgetting about it.
return floor(Int, pi * compact_support^2 / particle_spacing^2) | ||
end | ||
|
||
@inline @fastpow function ideal_neighbor_count(::Val{3}, particle_spacing, compact_support) |
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.
Please check the codecov report. This is not covered, but the 2D version is.
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 test for this exists in #584
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.
Can you add it here or does it require other code from #584?
# Section 2.2 in Akinci et al. 2013 "Versatile Surface Tension and Adhesion for SPH Fluids" | ||
# Note: This is the simplest form of normal approximation commonly used in SPH and comes | ||
# with serious deficits in accuracy especially at corners, small neighborhoods and boundaries | ||
function calc_normal_akinci!(system, neighbor_system::BoundarySystem, u_system, v, |
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.
Please check Codecov report. This is missing tests.
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.
Testing this doesn't make much sense. Since there is no analytical value. And it will change in all subsequent PRs.
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.
Let me restate that there is a analytical value but the results will not be close. Just closer than without it.
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.
There must be some useful way to test this. Maybe with a high resolution and very large smoothing length?
Depends on #599
extracted from #584