Skip to content

Commit

Permalink
particle beam and xyφ for interactive
Browse files Browse the repository at this point in the history
  • Loading branch information
Datseris committed Apr 19, 2020
1 parent 79af5cb commit ab6edc6
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
11 changes: 8 additions & 3 deletions docs/src/basic/high_level.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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φ
```
---

Expand Down
27 changes: 15 additions & 12 deletions src/billiards/billiardtable.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export Billiard, randominside
export Billiard, randominside, randominside_xyφ
#######################################################################################
## Billiard Table
#######################################################################################
Expand Down Expand Up @@ -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
29 changes: 26 additions & 3 deletions src/billiards/particles.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export AbstractParticle, Particle, MagneticParticle
export AbstractParticle, Particle, MagneticParticle, particlebeam
####################################################
## Particles
## Particle
####################################################
"""
AbstractParticle
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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

0 comments on commit ab6edc6

Please sign in to comment.