TopOpt.jl provides only a global volume-fraction constraint via VolumeFun (src/Functions/volume.jl), bounding the total Σ x_e V_e / Σ V_e. There is no way to bound material volume locally — i.e. require the volume fraction inside a neighborhood of every element to stay below a threshold. This is listed as a beginner-friendly contribution in the README.
A local volume constraint prevents material from over-concentrating in any one region; it is the standard mechanism for infill/porous microstructure, discouraging member clustering, and controlling feature size.
Proposal: add a differentiable LocalVolumeFun following the Fun-suffix convention. It builds the same cell-neighborhood map as DensityFilterFun (FilterMetadata / get_neighbour_info in src/CheqFilters/) and returns either a per-cell vector (mirroring BlockComplianceFun) or an aggregate (max / p-norm / KS). It should extend AbstractFunction, remain Zygote-differentiable (rrule calling ChainRulesCore.unthunk), preserve PseudoDensities type parameters, and compose with the density filter.
Acceptance criteria: LocalVolumeFun in src/Functions/, finite-difference gradient tests, a feasibility test, and a docs entry.
Prepared with assistance from deepseek-v4-pro via opencode.
TopOpt.jl provides only a global volume-fraction constraint via
VolumeFun(src/Functions/volume.jl), bounding the totalΣ x_e V_e / Σ V_e. There is no way to bound material volume locally — i.e. require the volume fraction inside a neighborhood of every element to stay below a threshold. This is listed as a beginner-friendly contribution in the README.A local volume constraint prevents material from over-concentrating in any one region; it is the standard mechanism for infill/porous microstructure, discouraging member clustering, and controlling feature size.
Proposal: add a differentiable
LocalVolumeFunfollowing theFun-suffix convention. It builds the same cell-neighborhood map asDensityFilterFun(FilterMetadata/get_neighbour_infoinsrc/CheqFilters/) and returns either a per-cell vector (mirroringBlockComplianceFun) or an aggregate (max / p-norm / KS). It should extendAbstractFunction, remain Zygote-differentiable (rrule callingChainRulesCore.unthunk), preservePseudoDensitiestype parameters, and compose with the density filter.Acceptance criteria:
LocalVolumeFuninsrc/Functions/, finite-difference gradient tests, a feasibility test, and a docs entry.Prepared with assistance from deepseek-v4-pro via opencode.