kaipartmann / Peridynamics.jl

A Julia package for parallel peridynamics simulations
https://kaipartmann.github.io/Peridynamics.jl/
MIT License
32 stars 7 forks source link

Short range forces contact algorithm #107

Closed kaipartmann closed 1 week ago

kaipartmann commented 1 week ago

Add the short range forces contact algorithm as it was used in v0.2.

codecov[bot] commented 1 week ago

Codecov Report

Attention: Patch coverage is 91.48418% with 35 lines in your changes missing coverage. Please review.

Project coverage is 89.49%. Comparing base (c942dd0) to head (7ee026a).

Files Patch % Lines
src/core/threads_multibody_data_handler.jl 78.26% 10 Missing :warning:
src/auxiliary/io.jl 93.42% 5 Missing :warning:
src/core/data_handler.jl 50.00% 4 Missing :warning:
src/discretization/multibody_setup.jl 89.74% 4 Missing :warning:
src/time_solvers/velocity_verlet.jl 92.50% 3 Missing :warning:
src/auxiliary/mpi.jl 0.00% 2 Missing :warning:
src/core/mpi_body_data_handler.jl 92.59% 2 Missing :warning:
src/physics/short_range_force_contact.jl 96.92% 2 Missing :warning:
src/core/threads_body_data_handler.jl 94.44% 1 Missing :warning:
src/core/time_solvers.jl 0.00% 1 Missing :warning:
... and 1 more
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #107 +/- ## ========================================== + Coverage 89.17% 89.49% +0.32% ========================================== Files 42 44 +2 Lines 2752 2998 +246 ========================================== + Hits 2454 2683 +229 - Misses 298 315 +17 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

kaipartmann commented 1 week ago

Contact is now working:

using Peridynamics

function sphere_impact(path)
    Ø = 0.15
    ΔX0_sphere = Ø / 8
    pos_sphere, vol_sphere = uniform_sphere(Ø, ΔX0_sphere; center_z=Ø / 2 + ΔX0_sphere)
    sphere = Body(BBMaterial(), pos_sphere, vol_sphere)
    failure_permit!(sphere, false)
    material!(sphere; horizon=3.1ΔX0_sphere, E=210e9, rho=8000, Gc=2000)
    velocity_ic!(sphere, :all_points, :z, -20)
    lxy, lz = 2.0, 0.1
    ΔX0_plate = lz / 4
    pos_plate, vol_plate = uniform_box(lxy, lxy, lz, ΔX0_plate; center_z=-lz / 2)
    plate = Body(BBMaterial(), pos_plate, vol_plate)
    material!(plate; horizon=3.1ΔX0_plate, E=27e9, rho=2700, Gc=10)
    ms = MultibodySetup(:sphere => sphere, :plate => plate)
    contact!(ms, :sphere, :plate; radius=min(ΔX0_sphere, ΔX0_plate))
    vv = VelocityVerlet(steps=2000)
    job = Job(ms, vv; path=path)
    submit(job)
    return nothing
end
sphere_impact

However, a strange performance difference can be seen when playing around with threaded_nhs_update: https://github.com/kaipartmann/Peridynamics.jl/blob/7ee026a020181d2fe5542e848a0ccbfcdeb8563b/src/physics/short_range_force_contact.jl#L70-L71

# `threaded_nhs_update=true`
#  49.821336 seconds (2.93 M allocations: 3.263 GiB, 0.13% gc time)

# `threaded_nhs_update=false`
#  12.587003 seconds (2.92 M allocations: 3.262 GiB, 0.71% gc time)
kaipartmann commented 1 week ago

The differences in performance (see https://github.com/kaipartmann/Peridynamics.jl/pull/107#issuecomment-2182414620) seem to be related to combining Polyester.@batch and Base.Threads. PointNeighbors.jl uses Polyester.@batch within the @threaded macro.

With threaded_nhs_update=true and changing all Threads.@threads calls in Peridynamics.jl, the following differences occur:

# `@threads :static`
#  49.821336 seconds (2.93 M allocations: 3.263 GiB, 0.13% gc time)

# `@threads`
#  27.514394 seconds (2.92 M allocations: 3.262 GiB, 0.39% gc time)

# `Polyester.@batch`
#  11.450976 seconds (2.34 M allocations: 3.199 GiB, 0.49% gc time)