`BubbleBath.Sphere`

— Type`Sphere(pos::NTuple{D,Real}, radius::Real) where D`

Create a `Sphere{D}`

object centered at `pos`

with radius `radius`

.

`BubbleBath.bubblebath!`

— Method```
bubblebath!(
spheres::Vector{Sphere{D}},
radius_pdf, ϕ_max::Real, extent::NTuple{D,Real};
min_distance::Real = 0.0, through_boundaries = false,
max_tries = 10000, max_fails = 100,
verbose = true, rng = default_rng()
) where D
```

In-place version of `bubblebath`

, adds new spheres to the `spheres`

vector, which can be already populated.

Here, `ϕ_max`

does **not** account for spheres that might already be present in the `spheres`

vector. E.g. if `packing_fraction(spheres, extent)`

is 0.2 and `ϕ_max=0.3`

, then the algorithm generates new spheres for a packing fraction of 0.3, which upon insertion will (try to) add up to a total packing fraction of 0.5. To account for the pre-initialized spheres, decrease `ϕ_max`

accordingly (`ϕ_max = 0.3-packing_fraction(spheres,extent)`

giving 0.1 for this example).

`BubbleBath.bubblebath!`

— Method```
bubblebath!(
spheres::Vector{Sphere{D}},
radii::Vector{<:Real}, extent::NTuple{D,Real};
min_distance::Real = 0.0, through_boundaries = false,
max_tries = 10000, max_fails = 100,
verbose = true, rng = default_rng()
) where D
```

In-place version of `bubblebath`

, adds new spheres to the `spheres`

vector (which can be already populated).

`BubbleBath.bubblebath`

— Method```
bubblebath(
radius_pdf, ϕ_max::Real, extent::NTuple{D,Real};
through_boundaries = false,
max_tries = 10000, max_fails = 100,
verbose = true
) where D
```

Generate a bath of spheres in the domain `extent`

, extracting radii from `radius_pdf`

trying to reach a target packing fraction `ϕ_max`

. The domain is filled with spheres in order of decreasing radius.

**Keywords**

`min_distance = 0.0`

: Minimum allowed distance between spheres. Negative values can be used to allow overlaps.`through_boundaries = false`

: Whether spheres can cross through the domain boundaries.`max_tries = 10000`

: Maximum number of insertion tries for each sphere. When`max_tries`

is reached, the sphere is discarded and the algorithm moves on to the next one.`max_fails = 100`

: Maximum number of failures (i.e. discarded spheres) allowed. Once`max_fails`

is reached, the program halts.`verbose = true`

: Whether info logs should be printed.`rng = Random.default_rng()`

: Random number generator.

If a negative `min_distance`

is used or `through_boundaries`

is set to true, the packing fraction estimated during the generation will not correspond to the real packing fraction of the system. In these cases, `ϕ_max`

has only a *semi*-quantitative value.

`BubbleBath.bubblebath`

— Method```
bubblebath(
radii::Vector{<:Real}, extent::NTuple{D,Real};
min_distance = 0.0,
through_boundaries = false,
max_tries = 10000, max_fails = 100,
verbose = true,
rng = default_rng()
) where D
```

Generate a bath of spheres with radii `radii`

in the domain `extent`

.

`BubbleBath.generate_radii`

— Method```
generate_radii(
radius_pdf, ϕ_max::Real, extent::NTuple{D,Real};
max_tries = 10000, verbose = true, rng = default_rng()
) where D
```

Generate a vector of radii from the `radius_pdf`

distribution, with a limit packing fraction `ϕ_max`

in the domain `extent`

.

`BubbleBath.is_inside_boundaries`

— Method`is_inside_boundaries(pos::NTuple{D,Real}, radius::Real, extent::NTuple{D,Real}) where D`

Check if a sphere of radius `radius`

centered at `pos`

is within domain `extent`

.

`BubbleBath.is_overlapping`

— Method`is_overlapping(p::NTuple{D,Real}, r::Real, spheres::Vector{Sphere{D}}) where D`

Test if a sphere of radius `r`

centered at `p`

overlaps with any sphere in `spheres`

. Surface contact is not counted as overlap.

`BubbleBath.is_overlapping`

— Method`is_overlapping(p₁::NTuple{D,Real}, r₁::Real, s₂::Sphere{D}) where D`

Test if a sphere of radius `r₁`

centered at `p₁`

overlaps with sphere `s₂`

. Surface contact is not counted as overlap.

`BubbleBath.is_overlapping`

— Method`is_overlapping(p₁::NTuple{D,Real}, r₁::Real, p₂::NTuple{D,Real}, r₂::Real) where D`

Test if two spheres with radii `r₁`

and `r₂`

, centered at `p₁`

and `p₂`

respectively, are overlapping. Surface contact is not counted as overlap.

`BubbleBath.is_walkable`

— Method```
is_walkable(
pos::NTuple{D,<:Real}, r::Real, spheres::AbstractVector{Sphere{D}},
extent::NTuple{D,<:Real}, boundaries::Symbol
) where D
```

Determines whether an object of size `r`

can occupy position `pos`

in a domain `extent`

filled by `spheres`

.

`BubbleBath.packing_fraction`

— Method`packing_fraction(wm::BitArray)`

Evaluate the packing fraction in a walkmap `wm`

.

If `wm`

was generated with `probe_radius=0`

this represents the real packing fraction, instead if `probe_radius`

was not zero, it represents the effective packing fraction experienced by the probe.

Unlike the other instances of `packing_fraction`

, this one is exact, independently of overlaps and boundary conditions, within the resolution of the walkmap.

`BubbleBath.packing_fraction`

— Method`packing_fraction(spheres::Vector{Sphere{D}}, extent::NTuple{D,Real}) where D`

Evaluate the packing fraction of `spheres`

in domain `extent`

. This measurement is not exact if spheres are overlapping or cross through the domain boundaries.

`BubbleBath.packing_fraction`

— Method`packing_fraction(radii::Vector{Real}, extent::NTuple{D,Real}) where D`

Evaluate the packing fraction of a collection of spheres with radii `radii`

in domain `extent`

. This measurement is not exact if spheres are overlapping or cross through the domain boundaries.

`BubbleBath.volume`

— Method`volume(r::Real, D::Int)`

Evaluate volume of a sphere of radius `r`

in `D`

dimensions. Only D=2 and D=3 currently supported.

`BubbleBath.volume`

— Method`volume(sphere::Sphere{2})`

Evaluate volume of two-dimensional sphere, i.e. the area of a circle (πr²).

`BubbleBath.volume`

— Method`volume(sphere::Sphere{3})`

Evaluate volume of a three-dimensional sphere (4πr³/3)

`BubbleBath.walkmap`

— Method```
walkmap(
spheres::AbstractVector{Sphere{D}}, extent::NTuple{D,<:Real},
resolution::Real, probe_radius::Real = 0;
boundaries::Symbol = :cut
) where D
```

Generate a walkmap for the given configuration of `spheres`

in the domain `extent`

, with the desired `resolution.`

A positive `probe_radius`

restricts the walkable space assuming that the "probe" has a finite size.

`boundaries`

can be set to `:cut`

or `:wrap`

to define how to deal with spheres that cross through the domain boundaries (in case there is any).