From ab6edc6658e214154464a8d91f92113d28fb4c22 Mon Sep 17 00:00:00 2001 From: Datseris Date: Sun, 19 Apr 2020 11:58:42 +0200 Subject: [PATCH] =?UTF-8?q?particle=20beam=20and=20xy=CF=86=20for=20intera?= =?UTF-8?q?ctive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ Project.toml | 2 +- docs/src/basic/high_level.md | 11 ++++++++--- src/billiards/billiardtable.jl | 27 +++++++++++++++------------ src/billiards/particles.jl | 29 ++++++++++++++++++++++++++--- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8de525be..a1884fb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# 3.11.0 +* `particlebeam` and `randominside_xyφ` functions. # 3.10.0 * It is now possible in `timeseries!` to evolve a particle until a certain boolean condition is met. diff --git a/Project.toml b/Project.toml index ab0e2434..d98debf7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DynamicalBilliards" uuid = "4986ee89-4ee5-5cef-b6b8-e49ba721d7a5" repo = "https://github.com/JuliaDynamics/DynamicalBilliards.jl.git" -version = "3.10.2" +version = "3.11.0" [deps] Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" diff --git a/docs/src/basic/high_level.md b/docs/src/basic/high_level.md index 23c2aef9..a0b4b4dd 100644 --- a/docs/src/basic/high_level.md +++ b/docs/src/basic/high_level.md @@ -36,8 +36,7 @@ Currently there are two types of particles: * [`Particle`](@ref), which propagates as a straight line. * [`MagneticParticle`](@ref), which propagates as a circle instead of a line (similar to electrons in a perpendicular magnetic field). -There are two ways to create a particle. The first one is to provide the -constructor with some initial conditions: +To make a particle, provide the constructor with some initial conditions: ```@example 2 x0 = rand(); y0 = rand(); φ0 = 2π*rand() @@ -53,14 +52,20 @@ mp = MagneticParticle(x0, y0, φ0, ω) When creating a billiard or a particle, the object is printed with `{Float64}` at the end. This shows what type of numbers are used for *all* numerical operations. If you are curious you can learn more about it in the [Numerical Precision](@ref). +You can initialize several particles with the same direction but slightly different position is the following function: +```@docs +particlebeam +``` + !!! danger "Particles must be inside the Billiard!" Keep in mind that the particle must be initialized **inside a billiard** for any functionality to work properly and make sense. If you are not sure what we mean by that, then you should check out the [Internals](@ref) page. ## Random initial conditions -If you have a `Billiard` which is not a rectangle, creating many random initial conditions inside it can be a pain. Fortunately, the second way to create a particle is to use the following function: +If you have a `Billiard` which is not a rectangle, creating many random initial conditions inside it can be a pain. Fortunately, we have the following function: ```@docs randominside +randominside_xyφ ``` --- diff --git a/src/billiards/billiardtable.jl b/src/billiards/billiardtable.jl index f80fbd73..643920d5 100644 --- a/src/billiards/billiardtable.jl +++ b/src/billiards/billiardtable.jl @@ -1,4 +1,4 @@ -export Billiard, randominside +export Billiard, randominside, randominside_xyφ ####################################################################################### ## Billiard Table ####################################################################################### @@ -122,37 +122,40 @@ function cellsize( end """ - randominside(bd::Billiard [, ω]) -Return a particle with random allowed initial conditions inside the given + randominside(bd::Billiard [, ω]) → p +Return a particle `p` with random allowed initial conditions inside the given billiard. If supplied with a second argument the type of the returned particle is `MagneticParticle`, with angular velocity `ω`. **WARNING** : `randominside` works for any **convex** billiard but it does not work for non-convex billiards. (this is because it uses `distance`) """ -randominside(bd::Billiard) = Particle(_randominside(bd)...) -randominside(bd::Billiard{T}, ω) where {T} = +randominside(bd::Billiard, ω::Nothing = nothing) = Particle(_randominside(bd)...) +randominside(bd::Billiard{T}, ω::Real) where {T} = MagneticParticle(_randominside(bd)..., T(ω)) - - -function _randominside(bd::Billiard{T}) where {T<:AbstractFloat} - #1. position +""" + randominside_xyφ(bd::Billiard) → x, y, φ +Same as [`randominside`](@ref) but only returns position and direction. +""" +function randominside_xyφ(bd::Billiard{T}) where {T<:AbstractFloat} xmin::T, ymin::T, xmax::T, ymax::T = cellsize(bd) xp = T(rand())*(xmax-xmin) + xmin yp = T(rand())*(ymax-ymin) + ymin pos = SV{T}(xp, yp) dist = distance_init(pos, bd) - while dist <= sqrt(eps(T)) xp = T(rand())*(xmax-xmin) + xmin yp = T(rand())*(ymax-ymin) + ymin pos = SV{T}(xp, yp) dist = distance_init(pos, bd) end + return pos[1], pos[2], T(2π*rand()) +end - #2. velocity - φ = T(2π*rand()) +function _randominside(bd::Billiard{T}) where {T<:AbstractFloat} + x, y, φ = randominside_xyφ(bd) + pos = SV{T}(x, y) vel = SV{T}(sincos(φ)...) return pos, vel, zero(SV{T}) # this zero is the `current_cell` end diff --git a/src/billiards/particles.jl b/src/billiards/particles.jl index 7da8a6bc..fb428622 100644 --- a/src/billiards/particles.jl +++ b/src/billiards/particles.jl @@ -1,6 +1,6 @@ -export AbstractParticle, Particle, MagneticParticle +export AbstractParticle, Particle, MagneticParticle, particlebeam #################################################### -## Particles +## Particle #################################################### """ AbstractParticle @@ -52,7 +52,9 @@ print(io, "Particle{$T}\n", "position: $(p.pos+p.current_cell)\nvelocity: $(p.vel)") - +#################################################### +## MagneticParticle +#################################################### """ ```julia MagneticParticle(ic::AbstractVector{T}, ω::Real) # where ic = [x0, y0, φ0] @@ -134,3 +136,24 @@ function cyclotron(p, use_cell) pos = use_cell ? p.pos + p.current_cell : p.pos return pos, p.r end + +#################################################### +## Aux +#################################################### +""" + particlebeam(x0, y0, φ, N, dx, ω = nothing) → ps +Make `N` particles, all with direction `φ`, starting at `x0, y0`. The particles +don't all have the same position, but are instead spread by up to `dx` in the +direction normal to `φ`. +""" +function particlebeam(x0, y0, φ, N, dx, ω = nothing, T = Float64) + n = sincos(φ) + xyφs = [ + T.((x0 + i*dx*n[1]/N, y0 + i*dx*n[2]/N, φ)) for i in range(-N/2, N/2; length = N) + ] + if isnothing(ω) + ps = [Particle(z...) for z in xyφs] + else + ps = [MagneticParticle(z..., T(ω)) for z in xyφs] + end +end