API — Particle assemblies
MeanFieldHomogenization.Assemblies Module
MeanFieldHomogenization.AssembliesAssemblies of individually located inclusions, and the two N-body schemes that act on them.
Every other cell of the package describes a microstructure statistically — an RVE by volume fractions, a Laminate by a stacking order. That is all a one-site scheme can use, and it is not enough here: the field one inclusion induces in another depends on the vector joining their centers. Hence ParticleAssembly, a cell that carries positions.
Two schemes consume it, and they share both the cell and the interaction kernel of MeanFieldHomogenization.Interactions:
ClusterModel— Molinari & El Mouden (1996), solving for the mean strain of every inclusion inside a cluster of neighbors;EquivalentInclusion— [2], a Galerkin discretization of the weak Lippmann-Schwinger equation, which additionally delivers a rigorous bound on the apparent stiffness.
Contents
assembly.jl:Particle, the boundary treatments (MixedBC,PeriodicBox), theParticleAssemblycell and itsAbstractHomogenizationCellcontractgenerators.jl: cubic lattices and hard-particle random microstructuresblock_solve.jl: linear systems whose unknowns are tensors, flattened onto the Kelvin-Mandel basiscluster_model.jl: the Molinari & El Mouden kerneleim.jl: the equivalent-inclusion kernelas_rve.jl:RVE(asm)— forget the positions, keep the fractions, which is what makes every one-site scheme of the package available on an assemblyparameters.jl: parameter lenses (positions, radii) for the differentiation entry points
The cell
MeanFieldHomogenization.Assemblies.ParticleAssembly Type
ParticleAssembly{T<:Number, B<:AbstractAssemblyBoundary} <: AbstractHomogenizationCellA matrix holding individually located inclusions — the cell the N-body schemes EquivalentInclusion and ClusterModel act on.
Fields:
matrix_name::Symbolandmatrix_properties::Dict{Symbol,Any}— the reference phase, which is also the reference medium of both models;particle_names::Vector{Symbol}— particles in insertion order;particles::Dict{Symbol,Particle}— position, geometry and moduli of each;boundary::B—MixedBCorPeriodicBox;families::Dict{Symbol,Int}— family label per particle. Particles sharing a label are constrained to carry the same polarization or localization tensor, which is how a lattice with a small motif is described without repeating its equations. Defaults to one family per particle.
Construction is two-step, mirroring RVE and Laminate:
asm = ParticleAssembly(; boundary = PeriodicBox(1.0; cutoff = 3.0))
add_matrix!(asm, Dict(:C => C_m))
add_particle!(asm, :p1, (0.0, 0.0, 0.0), Ellipsoid(0.3), Dict(:C => C_i))
homogenize(asm, ClusterModel(), :C)See also add_particle!, particle_volume_fraction, assembly_volume, validate_assembly.
MeanFieldHomogenization.Assemblies.Particle Type
Particle(center, geometry, properties)One individually located inclusion of a ParticleAssembly: where it is, what shape it has, and what it is made of.
Unlike a Phase, a particle is a single object rather than a population — it carries no volume fraction, since the fraction follows from its volume and the size of the cell.
A property value may be a Homogenized cell + scheme, resolved lazily at homogenize time exactly as in an RVE.
MeanFieldHomogenization.Assemblies.add_matrix! Function
add_matrix!(asm::ParticleAssembly, properties) -> asmSet the matrix properties of an assembly. The matrix is also the reference medium of both N-body models — neither uses a reference distinct from the matrix, following the papers they come from.
MeanFieldHomogenization.Assemblies.add_particle! Function
add_particle!(asm, name, center, geometry, properties; family = nothing) -> asmAdd one located inclusion to the assembly.
family groups particles that must share the same unknown. Leaving it unset gives the particle a family of its own, which is what a random assembly wants; passing an explicit label is how a periodic motif with symmetric particles is declared without duplicating equations.
MeanFieldHomogenization.Assemblies.validate_assembly Function
validate_assembly(asm) -> asmCheck that an assembly is solvable: a matrix is present, at least one particle is present, all particles share the same dimension, the total volume fraction is below one, and no two particles overlap.
The overlap check is not pedantry — the interaction kernel is only defined for disjoint regions, and an overlap would otherwise surface much later as a DomainError from deep inside a lattice sum. Overlap is tested between the bounding spheres of the particles, which is exact for spherical particles and conservative otherwise.
Boundary treatments
MeanFieldHomogenization.Assemblies.AbstractAssemblyBoundary Type
AbstractAssemblyBoundaryHow a ParticleAssembly closes its far field. This is the one place where the two N-body models of the package genuinely differ: they solve the same linear system and differ in what surrounds the cell.
MeanFieldHomogenization.Assemblies.MixedBC Type
MixedBC(shape) <: AbstractAssemblyBoundaryMixed boundary conditions of [2]: the statistical volume element shape — which must be an ellipsoid, since the derivation leans on Eshelby's theorem for the domain itself — is embedded in an infinite medium of the matrix stiffness, subject to a uniform strain at infinity plus a uniform surface traction chosen so that the loading parameter coincides with the macroscopic strain.
Its practical virtue is that no periodization is needed: the far field is closed by a single correction term involving the Hill tensor of the SVE domain,
MixedBC(radius) is shorthand for a spherical (3D) SVE; pass an Ellipsoid for anything else.
MeanFieldHomogenization.Assemblies.PeriodicBox Type
PeriodicBox(period; cutoff = 3 * period) <: AbstractAssemblyBoundaryPeriodic elementary representative volume of [1]: the cubic cell of side period tiles space, each particle carrying a family of periodic images, and the interaction sums are truncated to the images lying within cutoff of the receiver.
The cutoff is a sphere, not a box, and that is not cosmetic: Molinari & El Mouden's Appendix B proves convergence from the vanishing of the interaction kernel integrated over the exterior of a sphere. Their own convergence study finds the estimate stable beyond cutoff ≈ 2 · period; the default of three periods is comfortably inside that plateau.
cutoff = 0 reduces every cluster to its own receiver, which is the degenerate case in which the cluster model collapses exactly onto Mori-Tanaka (their Appendix C) — a useful thing to be able to ask for.
The bridge to the one-site schemes
MeanFieldHomogenization.Schemes.RVE Method
RVE(asm::ParticleAssembly; matrix_geometry = nothing, distribution_shape = nothing)Statistical view of an assembly: forget the positions, keep everything else. Returns an RVE whose matrix carries the assembly's matrix properties and which has one phase per particle, each with that particle's geometry, properties and derived volume fraction
This is the bridge that makes every one-site scheme available on an assembly. It is applied automatically by homogenize — homogenize(asm, MoriTanaka(), :C) just works — and is exported so that the intermediate cell can be inspected:
asm = cubic_lattice(:sc, Dict(:C => C_m), Dict(:C => C_i); fraction = 0.3)
homogenize(asm, ClusterModel(), :C) # sees the positions
homogenize(asm, MoriTanaka(), :C) # goes through RVE(asm); ignores them
rve = RVE(asm) # …and here it is, to look atmatrix_geometry is the shape the matrix phase is given. An assembly has no matrix shape of its own, so it defaults to a ball (a disk in 2D) — the neutral, orientation-free choice, and the one the one-site scripts of the package use. It is read by the schemes that localize every phase alike — the self-consistent family and the bounds — and ignored by MoriTanaka, Dilute, Maxwell and PCW, which need the matrix property only.
distribution_shape is forwarded to the RVE constructor and is what PonteCastanedaWillis needs; an assembly carries no such statistical descriptor, so it must be supplied here if that scheme is wanted.
One phase per particle
The conversion does not merge identical particles. It does not need to: every scheme sums over phases linearly, so N identical phases of fraction f/N give exactly the same effective property as one phase of fraction f. Keeping them apart avoids an equality heuristic on geometries and preserves the particle names.
There is no way back
RVE(asm) discards the positions, which is the whole point — but it means the result can no longer feed ClusterModel or EquivalentInclusion. Those need the assembly itself.
See also ParticleAssembly, particle_volume_fraction.
Accessors
MeanFieldHomogenization.Assemblies.matrix_property Function
matrix_property(asm, key) -> valueProperty key of the matrix, resolving a Homogenized value if one is stored. This is also the reference medium of both N-body models.
MeanFieldHomogenization.Assemblies.matrix_volume_fraction Function
matrix_volume_fraction(asm) -> RealVolume fraction of the matrix, 1 - Σ_a f_a.
MeanFieldHomogenization.Assemblies.particle_names Function
particle_names(asm) -> Vector{Symbol}Particle names in insertion order.
MeanFieldHomogenization.Assemblies.particle Function
particle(asm, name) -> ParticleThe stored Particle of the given name.
MeanFieldHomogenization.Assemblies.particle_center Function
particle_center(asm, name) -> AbstractVectorCenter of a particle.
MeanFieldHomogenization.Assemblies.particle_geometry Function
particle_geometry(asm, name) -> AbstractInclusionGeometry of a particle.
MeanFieldHomogenization.Assemblies.particle_property Function
particle_property(asm, name, key) -> valueProperty key of particle name, resolving a Homogenized value if one is stored (declarative multiscale nesting). Use cell_container_property for the raw stored value.
MeanFieldHomogenization.Assemblies.particle_family Function
particle_family(asm, name) -> IntFamily label of a particle. Particles sharing a label share their unknown.
MeanFieldHomogenization.Assemblies.family_labels Function
family_labels(asm) -> Vector{Int}Distinct family labels, in order of first appearance.
MeanFieldHomogenization.Assemblies.particle_volume Function
particle_volume(asm, name) -> RealVolume (3D) or area (2D) of one particle.
MeanFieldHomogenization.Assemblies.particle_volume_fraction Function
particle_volume_fraction(asm, name) -> RealVolume fraction f_a = |Ω_a| / |Ω| of one particle. Derived from the geometry and the boundary, never stored — so it cannot disagree with the microstructure it describes.
MeanFieldHomogenization.Assemblies.inclusion_volume_fraction Function
inclusion_volume_fraction(asm) -> RealTotal volume fraction of the particles, Σ_a f_a.
MeanFieldHomogenization.Assemblies.assembly_volume Function
assembly_volume(asm) -> RealMeasure of the cell: the volume of the SVE for MixedBC, Lᵈ for a PeriodicBox. It is what turns particle volumes into volume fractions.
Generators
MeanFieldHomogenization.Assemblies.cubic_lattice Function
cubic_lattice(kind, matrix_properties, particle_properties;
fraction = nothing, radius = nothing, period = 1.0,
cutoff = nothing, name_prefix = :p, T = Float64)
-> ParticleAssemblyBuild a ParticleAssembly on the simple-cubic (:sc), body-centered (:bcc) or face-centered (:fcc) cubic lattice of equal spheres, with PeriodicBox boundary conditions.
Give exactly one of fraction (total volume fraction of the spheres) or radius. cutoff is forwarded to PeriodicBox; the default of three periods sits inside the convergence plateau reported by [1].
particle_properties may be a single property dictionary — applied to every site — or a vector of dictionaries, one per site of the motif, which is how a multi-phase array such as their BCC arrangement of alternating voids and rigid spheres is described. Sites carrying different properties are given different families.
asm = cubic_lattice(:sc, Dict(:C => C_m), Dict(:C => C_i); fraction = 0.3)
homogenize(asm, ClusterModel(), :C)MeanFieldHomogenization.Assemblies.random_assembly Function
random_assembly(n, matrix_properties, particle_properties;
fraction = nothing, radius = nothing, period = 1.0,
rng = Random.default_rng(), cycles = 20_000,
boundary = nothing, dim = 3, T = Float64)
-> ParticleAssemblyBuild a ParticleAssembly of n equal, non-overlapping spheres (dim = 3) or disks (dim = 2) by the hard-particle Metropolis algorithm used by [2], §5.
The particles start on a regular lattice and are then shuffled by cycles sweeps of trial moves, the move amplitude being re-tuned every 50 sweeps to hold the acceptance ratio near 0.3 — the recipe of the paper. Overlap is tested in the periodic metric, so the resulting microstructure tiles space whatever boundary treatment is then applied.
Pass rng explicitly for reproducibility; the default boundary is a PeriodicBox of the given period, and boundary = MixedBC(...) selects Brisard's ellipsoidal SVE instead.
MeanFieldHomogenization.Assemblies.max_packing_fraction Function
max_packing_fraction(kind::Symbol) -> Float64Largest volume fraction of equal, non-overlapping spheres on the cubic lattice kind (:sc, :bcc or :fcc) — the point at which neighboring spheres touch: π/6 ≈ 0.5236, √3π/8 ≈ 0.6802 and √2π/6 ≈ 0.7405.
Worth knowing when reading Molinari & El Mouden's figures: their simple-cubic curves stop near f = 0.52 for exactly this reason.
The N-body schemes
MeanFieldHomogenization.Schemes.ClusterModel Type
ClusterModel(; cluster_radius = nothing, kwargs...) <: HomogenizationSchemeCluster model of [1]: an N-body scheme in which the mean strain of every inclusion is solved for, accounting for the pairwise interaction with every neighbor inside a cluster of radius R_c, on top of the interaction with the matrix.
Acts on a ParticleAssembly, not on an RVE. Writing
with interaction_tensor) over the cluster. cluster_radius overrides the cutoff carried by the assembly's PeriodicBox.
Reducing the cluster to a single inclusion (cluster_radius = 0) makes every MoriTanaka — the identity proved in Appendix C of the paper, and the sharpest available check on an implementation.
MeanFieldHomogenization.Schemes.EquivalentInclusion Type
EquivalentInclusion(; order = 0, kwargs...) <: HomogenizationSchemeEquivalent inclusion method in the variational (Galerkin) form of [2] — a Galerkin discretization of the weak form of the Lippmann-Schwinger equation, with the polarization taken piecewise constant over each inclusion at order = 0.
Acts on a ParticleAssembly. The polarizations solve
and the apparent stiffness follows from MixedBC no periodization and no conditionally convergent lattice sum are needed.
Because the method minimizes a Hashin-Shtrikman functional over a finite-dimensional space, the estimate is a rigorous bound on the apparent stiffness whenever the matrix is stiffer (upper bound) or softer (lower bound) than every inhomogeneity — see eim_bound_type.
Brisard et al. note in their §3.1 that at order = 0 their influence pseudotensors coincide with the interaction tensors of [63] and [1]; the two schemes of this package accordingly share interaction_tensor and agree on a periodic assembly with the same cutoff.
MeanFieldHomogenization.Assemblies.eim_bound_type Function
eim_bound_type(asm, prop = :C) -> SymbolWhether the EquivalentInclusion estimate of property prop is a rigorous bound on the apparent stiffness of the assembly, and which one:
:upper— the matrix is stiffer than every inhomogeneity;:lower— the matrix is softer than every inhomogeneity;:none— the contrasts have mixed signs, and the estimate is only an estimate.
This is the extremum property of [2], §3.2, inherited from the Hashin-Shtrikman variational principle. It also implies that the estimate improves monotonically with the polarization order.
Definiteness is tested on the Kelvin-Mandel matrix of the contrast
MeanFieldHomogenization.Assemblies.eim_polarizations Function
eim_polarizations(asm, prop = :C; kw...) -> (Vector, Vector{Symbol})Per-particle polarization operators of the EquivalentInclusion solution, together with the particle names, without going through homogenize.
Local fields follow directly: the strain operator of particle a is
MeanFieldHomogenization.Assemblies.cluster_localizations Function
cluster_localizations(asm, prop = :C; cluster_radius = nothing, kw...)
-> (Vector, Vector{Symbol})Per-family localization tensors of the ClusterModel solution, together with the representative particle of each family.
A[k] maps the macroscopic strain onto the mean strain of family k, so the mean stress follows as
Parameter lenses
MeanFieldHomogenization.Assemblies.CenterParameter Type
CenterParameter(name::Symbol, component::Int) <: AbstractParameterLens onto one Cartesian component of the center of particle name — the microstructural degree of freedom that no other cell of the package has.
derivative(asm, ClusterModel(), center_param(:p2, 3); indexer = C -> get_array(C)[1,1,1,1])MeanFieldHomogenization.Assemblies.RadiusParameter Type
RadiusParameter(name::Symbol, axis::Int) <: AbstractParameterLens onto one semi-axis of the geometry of particle name. For a sphere every axis is the radius, and setting one sets all of them — otherwise the geometry would silently stop being a sphere and change its shape class mid-derivative.
MeanFieldHomogenization.Assemblies.center_param Function
center_param(name, component) -> CenterParameterConvenience constructor for CenterParameter.
MeanFieldHomogenization.Assemblies.radius_param Function
radius_param(name, axis = 1) -> RadiusParameterConvenience constructor for RadiusParameter.