MultiGridBarrier 0.11.15
MultiGridBarrier is a Julia module for solving nonlinear convex optimization problems in function spaces, such as p-Laplace problems. When regularity conditions are satisfied, the solvers are quasi-optimal.
The MultiGridBarrier module features finite element and spectral discretizations in 1d and 2d.
Finite elements
After installing MultiGridBarrier with the Julia package manager, in a Jupyter notebook, one solves a 1d p-Laplace problem as follows:
using MultiGridBarrier
plot(fem1d_solve(L=5,p=1.0,verbose=false));A 2d p-Laplace problem:
plot(fem2d_solve(L=3,p=1.0,verbose=false));Spectral elements
Solve a 1d p-Laplace problem using spectral methods as follows:
plot(spectral1d_solve(n=40,p=1.0,verbose=false));A 2d p-Laplace problem:
plot(spectral2d_solve(n=5,p=1.5,verbose=false));Solving $\infty$-Laplacians
For $p \geq 1$ and domain $\Omega$, the solution $u$ of the $p$-Laplace problem is the minimizer of $J(u) = \|\nabla u\|_{L^p(\Omega)}^p + \int_{\Omega} fu,$ where $u$ is in a suitable space of function satisfying, e.g. Dirichlet conditions, and $f$ is a forcing. This definition must be modified for the $\infty$-Laplace problem. Here we show how to minimize: $J(u) = \|\nabla u\|_{L^\infty(\Omega)}^p + \int_{\Omega} fu.$ We put $p=1$ for simplicity.
plot(fem1d_solve(L=5,p=1.0,state_variables=[:u :dirichlet; :s :uniform],verbose=false));Parabolic problems
A time-dependent problem:
plot(parabolic_solve(fem2d(L=3);h=0.1,verbose=false))Module reference
MultiGridBarrier.MultiGridBarrier — Modulemodule MultiGridBarrierMultiGridBarrier solves nonlinear convex optimization problems in function spaces using a barrier (interior-point) method accelerated by a multigrid hierarchy constructed from your chosen discretization (FEM or spectral). The package provides simple, high-level entry points as well as a general solver that accept a "geometry" and optional keywords.
A gentle introduction via the p-Laplacian
For a domain Ω ⊂ ℝᵈ and p ≥ 1, consider the variational problem
\[\min_{u} \; J(u) = \int_{\Omega} \|\nabla u\|_2^p + f\,u \, dx\]
subject to appropriate boundary conditions (e.g., homogeneous Dirichlet). The Euler–Lagrange equation gives the p-Laplace PDE:
\[\nabla \cdot \big(\|\nabla u\|_2^{p-2}\,\nabla u\big) = \tfrac{1}{p}\,f \quad \text{in } \Omega,\]
with the specified boundary conditions. This connection is obtained by integration by parts applied to the first variation of J(u).
Constrained linear reformulation with a slack variable
Introduce a slack $s(x) \geq \|\nabla u(x)\|_2^p$ and rewrite the objective using s:
\[\min_{u,\,s} \; \int_{\Omega} s + f\,u \, dx \quad \text{subject to}\quad s \ge \|\nabla u\|_2^p.\]
This is a convex optimization problem with a linear objective and convex constraints. In discrete form, we bundle the state into z, and apply a block "differential" operator D so that
\[D z = \begin{bmatrix} u \\ \nabla u \\ s \end{bmatrix}, \qquad c^\top = \begin{bmatrix} f & 0 & 1 \end{bmatrix}.\]
The problem becomes
\[\min_{z} \int_{\Omega} c(x)^\top \, (D z)(x) \, dx \quad \text{subject to}\quad (u,q,s) \in \mathcal{Q} := \{ s \ge \|q\|_2^p \}\ \text{pointwise},\]
which MultiGridBarrier solves by a barrier method. An illustrative (simple) barrier for $\mathcal{Q}$ is
\[\mathcal{F}(q,s) = -\log\!\big(s^{2/p} - \|q\|_2^2\big) - 2\log s,\]
and the method minimizes the barrier-augmented functional
\[\int_{\Omega} t\, c(x)^\top (D z)(x) + \mathcal{F}\!\big((D z)(x)\big) \, dx\]
for increasing barrier parameter t. Internally, the solve proceeds on a hierarchy of grids with damped Newton steps and line search, but these details are abstracted away.
How to use it (discretizations and solvers)
- Solve with a convenience wrapper (recommended to start):
sol = fem1d_solve(; kwargs...)sol = fem2d_solve(; kwargs...)sol = spectral1d_solve(; kwargs...)sol = spectral2d_solve(; kwargs...)
- Or call the general solver directly:
sol = amgb(geometry; kwargs...)→AMGBSOL
- The solution can be plotted by calling
plot(sol). If usingamgb()directly, you must construct a suitable geometry object:geometry = fem1d(; L=4)→ 1D FEM on [-1, 1] with 2^L elementsgeometry = fem2d(; L=2, K=...)→ 2D FEM (quadratic + bubble triangles)geometry = spectral1d(; n=16)→ 1D spectral (Chebyshev/Clenshaw–Curtis)geometry = spectral2d(; n=4)→ 2D spectral (tensor Chebyshev)
Quick examples
# 1D FEM p-Laplace
z = fem1d_solve(L=5, p=1.0).z
# 2D spectral p-Laplace
z = spectral2d_solve(n=8, p=2.0).z
# 2D FEM with custom boundary data
g_custom(x) = [sin(π*x[1])*sin(π*x[2]), 10.0]
z = fem2d_solve(L=3; p=1.0, g=g_custom).z
# Time-dependent (implicit Euler)
sol = parabolic_solve(fem2d(L=3); h=0.1)
# plot(sol) animates the first componentInputs and defaults (high level)
p::Real= 1.0: exponent in the p-Laplace termg,f: boundary/initial data and forcing; either as functionsg(x),f(x)or as gridsg_grid,f_gridDandstate_variables: symbolic specifications of which operators act on which variables (sane defaults provided based on the geometry’s dimension)Q: convex set (by default, a p-Laplace-compatible set viaconvex_Euclidian_power)verbose,logfile: visualization and logging- Advanced control:
tol,t,t_feasibility,line_search,stopping_criterion,finalize
What you get back
- Static solvers (
amgb,*_solve) return anAMGBSOLwith fields:z::X(typically Matrix{T}): solution on the finest grid (nodes × components)SOL_main,SOL_feasibility: per-phase diagnosticslog::String: textual log for debugginggeometry: theGeometryused to construct the multilevel operators
plot(sol)to visualize the first component. - The time-dependent solver
parabolic_solvereturns aParabolicSOLwith fields:geometry,ts::Vector,u::Array(nodes × components × timesteps)
plot(parabolic_sol)to animate usingts(see plot docs for timing options).
Utilities
interpolate(geometry, z, points): evaluate the discrete solution at arbitrary pointsplot(sol)orplot(geometry, z): plot 1D curves or 2D surfacesplot(geometry, ts, U; frame_time=..., embed_limit=..., printer=...): animate a time sequence at absolute timests(seconds), e.g., fromparabolic_solve- Convex set helpers:
convex_Euclidian_power,convex_linear,convex_piecewise,intersect
Errors and diagnostics
- Throws
AMGBConvergenceFailureif the feasibility subproblem or the main solve cannot converge - Set
verbose=truefor a progress bar; inspectSOL_main/feasibility andlogfor details
See also
- Discretizations:
fem1d,fem2d,spectral1d,spectral2d - Solvers:
amgb,fem1d_solve,fem2d_solve,spectral1d_solve,spectral2d_solve,parabolic_solve - Convex:
convex_Euclidian_power,convex_linear,convex_piecewise,intersect - Visualization & sampling:
plot,interpolate
Types reference
MultiGridBarrier.AMGBConvergenceFailure — TypeAMGBConvergenceFailure <: ExceptionThrown when the AMGB solver fails to converge (feasibility or main phase). Includes a descriptive message about the failure.
MultiGridBarrier.Convex — TypeConvex{T}Container for a convex constraint set used by AMGB.
Fields:
- barrier(x, y): barrier of the set
- cobarrier(x, yhat): barrier with slack for feasibility
- slack(x, y): initial slack value
Construct via helpers like convex_linear, convex_Euclidian_power, convex_piecewise, or intersect.
MultiGridBarrier.FEM1D — TypeFEM1D{T}1D FEM geometry descriptor. Field: L::Int (levels). Use with amgb.
MultiGridBarrier.FEM2D — TypeFEM2D{T}2D FEM geometry descriptor for quadratic+bubble triangles. Fields: K::Matrix{T} (3n×2 mesh), L::Int (levels). Use with amgb.
MultiGridBarrier.Geometry — TypeGeometry{T,X,W,M,Discretization}Container for discretization geometry and the multigrid transfer machinery used by AMGB.
Constructed by high-level front-ends like fem1d, fem2d, spectral1d, and spectral2d. It collects the physical/sample points, quadrature weights, per-level subspace embeddings, discrete operators (e.g. identity and derivatives), and intergrid transfer operators (refine/coarsen).
Type parameters
T: scalar numeric type (e.g. Float64)X: type of the point storage forx(typicallyMatrix{T}; may be any AbstractArray with size (n_nodes, dim))W: type of the weight storage forw(typicallyVector{T}; may be any AbstractVector)M: matrix type used for linear operators (e.g.SparseMatrixCSC{T,Int}orMatrix{T})Discretization: front-end descriptor (e.g.FEM1D{T},FEM2D{T},SPECTRAL1D{T},SPECTRAL2D{T})
Fields
discretization::Discretization: Discretization descriptor that encodes dimension and grid constructionx::X: Sample/mesh points on the finest level; size is (n_nodes, dim)w::W: Quadrature weights matchingx(length n_nodes)subspaces::Dict{Symbol,Vector{M}}: Per-level selection/embedding matrices for function spaces (keys commonly include:dirichlet,:full,:uniform). Each value is a vector of length L with one matrix per level.operators::Dict{Symbol,M}: Discrete operators defined on the finest level (e.g.:id,:dx,:dy). Operators at other levels are obtained viacoarsen_fine * operator * refine_fineinsideamg.refine::Vector{M}: Level-to-level refinement (prolongation) matrices for the primary state spacecoarsen::Vector{M}: Level-to-level coarsening (restriction) matrices for the primary state space
Notes
Geometryis consumed byamgto build anAMGhierarchy and by utilities likeinterpolateandplot.- The length of
refine/coarsenequals the number of levels L; the last entry is typically the identity.
MultiGridBarrier.SPECTRAL1D — TypeSPECTRAL1D{T}1D spectral geometry descriptor (Chebyshev). Field: n::Int (nodes). Use with amgb.
MultiGridBarrier.SPECTRAL2D — TypeSPECTRAL2D{T}2D spectral geometry descriptor (tensor Chebyshev). Field: n::Int (nodes per dim). Use with amgb.
Functions reference
Base.intersect — Methodintersect(U::Convex{T}, rest...) where {T}Return the intersection of convex domains as a single Convex{T}. Equivalent to convex_piecewise with all pieces active.
MultiGridBarrier.amgb — Methodamgb(geometry::Geometry{T,X,W,Mat,Discretization}=fem1d(); kwargs...) where {T, X, W, Mat, Discretization}Algebraic MultiGrid Barrier (AMGB) solver for nonlinear convex optimization problems in function spaces using multigrid barrier methods.
This is the main high-level entry point for solving p-Laplace and related problems using the barrier method with multigrid acceleration. The solver operates in two phases:
- Feasibility phase: Finds an interior point for the constraint set (if needed)
- Main optimization phase: Solves the barrier-augmented optimization problem
Arguments
geometry: Discretization geometry (default:fem1d()). Options:fem1d(L=n): 1D finite elements with 2^L elementsfem2d(L=n, K=mesh): 2D finite elementsspectral1d(n=m): 1D spectral with m nodesspectral2d(n=m): 2D spectral with m×m nodes
Keyword Arguments
Problem Specification
dim::Integer = amg_dim(geometry.discretization): Problem dimension (1 or 2), auto-detected from geometrystate_variables::Matrix{Symbol} = [:u :dirichlet; :s :full]: Solution components and their function spacesD::Matrix{Symbol} = default_D[dim]: Differential operators to apply to state variablesx = geometry.x: Mesh/sample points wherefandgare evaluated when they are functions
Problem Data
p::T = 1.0: Exponent for p-Laplace operator (p ≥ 1)g::Function = default_g(T)[dim]: Boundary conditions/initial guess (function of spatial coordinates)g_grid::X(same container type asx): Alternative tog, directly provide values on grid (default:gevaluated atx)f::Function = default_f(T)[dim]: Forcing term/cost functional (function of spatial coordinates)f_grid::X(same container type asx): Alternative tof, directly provide values on grid (default:fevaluated atx)Q::Convex{T} = convex_Euclidian_power(T, idx=2:dim+2, p=x->p): Convex constraint set
Output Control
verbose::Bool = true: Display progress bar during solvinglogfile = devnull: IO stream for logging (default: no file logging)
Solver Control (passthrough)
Additional keyword arguments are forwarded to the internal solvers:
tol = sqrt(eps(T)): Barrier tolerance; the method stops once1/t > 1/tolt = T(0.1): Initial barrier parameter for the main solvet_feasibility = t: Initial barrier parameter for the feasibility solvemaxit = 10000: Maximum number of outer (barrier) iterationskappa = T(10.0): Multiplier controlling barrier growth (t ← min(kappa*t, ...))c0 = T(0): Base offset added to the objective (c0 + t*c)early_stop = z->false: Callbackz -> Bool; iftrue, halt early (e.g. after feasibility is reached)max_newton = ceil((log2(-log2(eps(T))))+2): Max Newton iterations per inner solvestopping_criterion = stopping_inexact(sqrt(minimum(M[1].w))/2, T(0.5)): Newton stopping rule- use
stopping_exact(theta)orstopping_inexact(lambda_tol, theta)
- use
line_search = linesearch_backtracking(T): Line search strategy (linesearch_backtrackingorlinesearch_illinois)finalize = stopping_exact(T(0.5)): Extra final Newton pass with stricter stoppingprogress = x->nothing: Progress callback in [0,1]; whenverbose=truethis is set internallyprintlog = (args...)->nothing: Logging callback; overridden bylogfilewhen usingamgb
Default Values
The defaults for f, g, and D depend on the problem dimension:
1D Problems
f(x) = [0.5, 0.0, 1.0]- Forcing termg(x) = [x[1], 2]- Boundary conditionsD = [:u :id; :u :dx; :s :id]- Identity, derivative, identity
2D Problems
f(x) = [0.5, 0.0, 0.0, 1.0]- Forcing termg(x) = [x[1]²+x[2]², 100.0]- Boundary conditionsD = [:u :id; :u :dx; :u :dy; :s :id]- Identity, x-derivative, y-derivative, identity
Returns
Solution object with fields:
z: Solution matrix of size(n_nodes, n_components)containing the computed solutionSOL_feasibility: Feasibility phase results (nothingif the initial point was already feasible), otherwise a solution object (see below)SOL_main: Main optimization phase results as a solution object (see below)log: String containing detailed iteration log for debugginggeometry: The inputgeometryobject
Each solution object (SOL_feasibility and SOL_main) is a NamedTuple containing:
z: Solution vector (flattened; for feasibility phase includes auxiliary slack variable)z_unfinalized: Solution before final refinement stepc: Cost functional used in this phaseits: Iteration counts across levels and barrier steps (L×k matrix where L is number of levels, k is number of barrier iterations)ts: Sequence of barrier parameters t used (length k)kappas: Step size multipliers used at each iteration (length k)times: Wall-clock timestamps for each iteration (length k)t_begin,t_end,t_elapsed: Timing information for this phasepassed: Boolean array indicating phase 1 success at each levelc_dot_Dz: Values of ⟨c, D*z⟩ at each barrier iteration (length k)
Algorithm Overview
The AMGB method combines:
- Interior point method: Uses logarithmic barriers to handle constraints
- Multigrid acceleration: Solves on hierarchy of grids from coarse to fine
- Damped Newton iteration: Inner solver with line search for robustness
The solver automatically handles:
- Construction of appropriate discretization and multigrid hierarchy
- Feasibility restoration when initial point is infeasible
- Adaptive barrier parameter updates with step size control
- Convergence monitoring across multiple grid levels
- Progress reporting (when
verbose=true) and logging (tologfileif specified)
Errors
Throws AMGBConvergenceFailure if:
- The feasibility problem cannot be solved (problem may be infeasible)
- The main optimization fails to converge within
maxititerations - Newton iteration fails at any grid level
Examples
# Solve 1D p-Laplace problem with p=1.5 using FEM
z = amgb(fem1d(L=4); p=1.5).z
# Solve 2D problem with spectral elements
z = amgb(spectral2d(n=8); p=2.0).z
# Custom boundary conditions
g_custom(x) = [sin(π*x[1])*sin(π*x[2]), 10.0]
z = amgb(fem2d(L=3); g=g_custom).z
# Get detailed solution information
sol = amgb(fem1d(L=3); verbose=true)
println("Iterations: ", sum(sol.SOL_main.its))
println("Final barrier parameter: ", sol.SOL_main.ts[end])
# Visualize the first component
plot(sol)
# Log iterations to a file
open("solver.log", "w") do io
amgb(fem2d(L=2); logfile=io, verbose=false)
endSee Also
fem1d_solve,fem2d_solve,spectral1d_solve,spectral2d_solve: Convenience wrappers for specific discretizationsConvex: Constraint set specification type
MultiGridBarrier.apply_D — Methodapply_D(D,z) = hcat([D[k]*z for k in 1:length(D)]...)MultiGridBarrier.convex_Euclidian_power — Methodconvex_Euclidian_power(::Type{T}=Float64; idx=Colon(), A=(x)->I, b=(x)->T(0), p=x->T(2))Create a convex set defined by Euclidean norm power constraints.
Constructs a Convex{T} object representing the power cone: {y : s ≥ ‖q‖₂^p} where [q; s] = A(x)*y[idx] + b(x)
This is the fundamental constraint for p-Laplace problems where we need s ≥ ‖∇u‖^p for some scalar field u.
Arguments
T::Type=Float64: Numeric type for computations
Keyword Arguments
idx=Colon(): Indices of y to which transformation appliesA::Function: Matrix functionx -> A(x)for linear transformationb::Function: Vector functionx -> b(x)for affine shiftp::Function: Exponent functionx -> p(x)where p(x) ≥ 1
Returns
Convex{T} object with logarithmic barrier for the power cone
Mathematical Details
The barrier function is:
- For p = 2:
-log(s² - ‖q‖²) - For p ≠ 2:
-log(s^(2/p) - ‖q‖²) - μ(p)*log(s)where μ(p) = 0 if p∈{1,2}, 1 if p<2, 2 if p>2
Examples
# Standard p-Laplace constraint: s ≥ ‖∇u‖^p
Q = convex_Euclidian_power(; idx=2:4, p=x->1.5)
# Spatially varying exponent
p_var(x) = 1.0 + 0.5 * x[1] # variable p
Q = convex_Euclidian_power(; p=p_var)
# Second-order cone constraint: s ≥ ‖q‖₂
Q = convex_Euclidian_power(; p=x->1.0)MultiGridBarrier.convex_linear — Methodconvex_linear(::Type{T}=Float64; idx=Colon(), A=(x)->I, b=(x)->T(0))Create a convex set defined by linear inequality constraints.
Defines F(x, y) = A(x) * y[idx] + b(x). The interior of the set is given by F(x, y) > 0 (a logarithmic barrier is applied to each component of F). The boundary F(x, y) = 0 corresponds to constraint activation.
Arguments
T::Type=Float64: Numeric type for computations
Keyword Arguments
idx=Colon(): Indices of y to which constraints apply (default: all)A::Function: Matrix functionx -> A(x)for constraint coefficientsb::Function: Vector functionx -> b(x)for constraint bounds
Returns
Convex{T} object with appropriate barrier functions
Examples
# Box constraints in 2D: -1 ≤ y ≤ 1
A_box(x) = [1.0 0.0; 0.0 1.0; -1.0 0.0; 0.0 -1.0]
b_box(x) = [1.0, 1.0, 1.0, 1.0]
Q = convex_linear(; A=A_box, b=b_box, idx=1:2)
# Single linear constraint: y[1] + 2*y[2] ≤ 3
# Choose F = 3 - (y1 + 2*y2) > 0
A_single(x) = [-1.0 -2.0]
b_single(x) = [3.0]
Q = convex_linear(; A=A_single, b=b_single, idx=1:2)MultiGridBarrier.convex_piecewise — Methodconvex_piecewise(::Type{T}=Float64; Q::Vector{Convex{T}}, select::Function=(tr=fill(true,length(Q));x->tr)) where {T}Build a Convex{T} that combines multiple convex domains with spatial selectivity.
Arguments
Q::Vector{Convex{T}}: a vector of convex pieces to be combined.select::Function: a functionx -> Vector{Bool}indicating which pieces are active atx. Default: all pieces active everywhere (equivalent to intersection).
Semantics
For sel = select(x), the resulting convex domain has:
barrier(x, y) = ∑(Q[k].barrier(x, y) for k where sel[k])cobarrier(x, yhat) = ∑(Q[k].cobarrier(x, yhat) for k where sel[k])slack(x, y) = max(Q[k].slack(x, y) for k where sel[k])
The slack is the maximum over active pieces, ensuring a single slack value suffices for feasibility at each x.
Use cases
- Intersections (default): All pieces active everywhere creates
Q₁ ∩ Q₂ ∩ ... - Spatial switching: Different constraints in different regions
- Conditional constraints: Activate constraints based on solution state
Examples
# Intersection (using default select)
U = convex_Euclidian_power(Float64; idx=[1, 3], p = x->2)
V = convex_linear(Float64; A = x->A_matrix, b = x->b_vector)
Qint = convex_piecewise(Float64; Q = [U, V]) # U ∩ V everywhere
# Region-dependent constraints
Q_left = convex_Euclidian_power(Float64; p = x->1.5)
Q_right = convex_Euclidian_power(Float64; p = x->2.0)
select(x) = [x[1] < 0, x[1] >= 0] # left half vs right half
Qreg = convex_piecewise(Float64; Q = [Q_left, Q_right], select = select)
# Conditional activation
Q_base = convex_linear(Float64; A = x->I, b = x->-ones(2))
Q_extra = convex_Euclidian_power(Float64; p = x->3)
select(x) = [true, norm(x) > 0.5] # extra constraint outside radius 0.5
Qcond = convex_piecewise(Float64; Q = [Q_base, Q_extra], select = select)See also: intersect, convex_linear, convex_Euclidian_power.
MultiGridBarrier.fem1d — Methodfem1d(::Type{T}=Float64; L=4, kwargs...)Construct 1D FEM geometry (piecewise linear) on [-1, 1]. Returns a Geometry suitable for use with amgb. Keyword L sets 2^L elements.
MultiGridBarrier.fem1d_solve — Methodfem1d_solve(::Type{T}=Float64;rest...) where {T} = amgb(fem1d(T;rest...);rest...)MultiGridBarrier.fem2d — Methodfem2d(::Type{T}=Float64; L=2, K=T[-1 -1;1 -1;-1 1;1 -1;1 1;-1 1], kwargs...)Construct 2D FEM geometry (quadratic + bubble) on a triangular mesh. Returns a Geometry suitable for use with amgb. Keywords: L levels, K 3n×2 vertices.
MultiGridBarrier.fem2d_solve — Methodfem2d_solve(::Type{T}=Float64;rest...) where {T} = amgb(fem2d(T;rest...);rest...)MultiGridBarrier.interpolate — Functioninterpolate(M::Geometry, z::Vector, t)Interpolate a solution vector at specified points.
Given a solution z on the mesh M, evaluates the solution at new points t using the appropriate interpolation method for the discretization.
Supported discretizations
- 1D FEM (
FEM1D): piecewise-linear interpolation - 1D spectral (
SPECTRAL1D): spectral polynomial interpolation - 2D spectral (
SPECTRAL2D): tensor-product spectral interpolation
Note: 2D FEM interpolation is not currently provided.
Arguments
M::Geometry: The geometry containing grid and basis informationz::Vector: Solution vector on the finest grid (length must match number of DOFs)t: Evaluation points. Format depends on dimension:- 1D: scalar or
Vector{T}of x-coordinates - 2D spectral:
Matrix{T}where each row is[x, y]
- 1D: scalar or
Returns
Interpolated values at the specified points. Shape matches input t.
Examples
# 1D interpolation (FEM)
geom = fem1d(L=3)
z = sin.(π .* vec(geom.x))
y = interpolate(geom, z, 0.5)
y_vec = interpolate(geom, z, [-0.5, 0.0, 0.5])
# 2D interpolation (spectral)
geom = spectral2d(n=4)
z = exp.(-geom.x[:,1].^2 .- geom.x[:,2].^2)
points = [0.0 0.0; 0.5 0.5; -0.5 0.5]
vals = interpolate(geom, z, points)MultiGridBarrier.parabolic_solve — Methodparabolic_solve(geometry::Geometry{T,X,W,Mat,Discretization}=fem2d(); kwargs...) where {T, X, W, Mat, Discretization}Solve time-dependent p-Laplace problems using implicit Euler timestepping.
Solves the parabolic PDE:
\[u_t - \nabla \cdot (\|\nabla u\|_2^{p-2}\nabla u) = -f_1\]
using implicit Euler discretization and barrier methods.
Arguments
geometry: Discretization geometry (default:fem2d()).
Keyword Arguments
Discretization
state_variables: State variables (default:[:u :dirichlet; :s1 :full; :s2 :full]).D: Differential operators (default depends on spatial dimension).dim::Int: Spatial dimension (auto-detected fromgeometry).
Time Integration
t0::T=0: Initial time.t1::T=1: Final time.h::T=0.2: Time step size.ts::AbstractVector{T}=t0:h:t1: Time grid; override to provide a custom, nonuniform, nondecreasing sequence.
Problem Parameters
p::T=1: Exponent for the p-Laplacian.f1: Source term function of signature(t, x) -> T(default:(t,x)->T(0.5)).g: Initial/boundary conditions function of signature(t, x) -> Vector{T}(default depends on dimension).Q: Convex constraints (default: appropriate for p-Laplace).
Output Control
verbose::Bool=true: Show a progress bar during time stepping.
Additional Parameters
rest...: Passed through toamgbfor each time step.
Returns
A ParabolicSOL with fields:
geometry: theGeometryused.ts::Vector{T}: time stamps (seconds).u::Array{T,3}: solution tensor of size(n_nodes, n_components, n_timesteps).
Animate with plot(sol) (or plot(sol, k) for component k). To save to a file, use the plotting printer, e.g. plot(sol; printer=anim->anim.save("out.mp4")).
Mathematical Formulation
The implicit Euler scheme $u_t \approx (u_{k+1}-u_k)/h$ gives:
\[u_{k+1} - h\nabla \cdot (\|\nabla u_{k+1}\|^{p-2}\nabla u_{k+1}) = u_k - h f_1.\]
We minimize the functional:
\[J(u) = \int_\Omega \tfrac{1}{2}u^2 + \tfrac{h}{p}\|\nabla u\|^p + (h f_1 - u_k)u \, dx.\]
With slack variables $s_1 \ge u^2$ and $s_2 \ge \|\nabla u\|^p$, this becomes:
\[\min \int_\Omega \tfrac{1}{2}s_1 + \tfrac{h}{p}s_2 + (h f_1 - u_k)u \, dx.\]
Examples
# Basic 2D heat equation (p=2)
sol = parabolic_solve(; p=2.0, h=0.1)
# 1D p-Laplace with custom parameters
sol = parabolic_solve(fem1d(L=5); p=1.5, h=0.05, t1=2.0)
# Spectral discretization
sol = parabolic_solve(spectral2d(n=8); verbose=true)
# Custom initial condition
g_init(t, x) = [exp(-10*(x[1]^2 + x[2]^2)), 0, 0]
sol = parabolic_solve(; g=g_init)See Also
MultiGridBarrier.spectral1d — Methodspectral1d(::Type{T}=Float64; n=16, kwargs...)Construct 1D spectral geometry with n Chebyshev nodes (degree n-1). Returns a Geometry suitable for use with amgb.
MultiGridBarrier.spectral1d_solve — Methodspectral1d_solve(::Type{T}=Float64;rest...) where {T} = amgb(spectral1d(T;rest...);rest...)MultiGridBarrier.spectral2d — Methodspectral2d(::Type{T}=Float64; n=4, kwargs...)Construct 2D spectral geometry with n×n Chebyshev nodes on [-1,1]^2. Returns a Geometry suitable for use with amgb.
MultiGridBarrier.spectral2d_solve — Methodspectral2d_solve(::Type{T}=Float64;rest...) where {T} = amgb(spectral2d(T;rest...);rest...)MultiGridBarrier.stopping_exact — Methodstopping_exact(theta::T) where {T}Create an exact stopping criterion for Newton methods.
Arguments
theta: tolerance parameter for gradient norm relative decrease (type T).
Returns
A stopping criterion function with signature: stop(ymin, ynext, gmin, gnext, n, ndecmin, ndec) -> Bool
where:
ymin: minimum objective value seen so far.ynext: current objective value.gmin: minimum gradient norm seen so far.gnext: current gradient vector.n: current Newton direction.ndecmin: square root of minimum Newton decrement seen so far.ndec: square root of current Newton decrement.
Algorithm
Returns true (stop) if both conditions hold:
- No objective improvement:
ynext ≥ ymin - Gradient norm stagnation:
‖gnext‖ ≥ theta * gmin
Notes
This criterion is "exact" in the sense that it requires both objective and gradient stagnation before stopping, making it suitable for high-precision optimization. Typical values of theta are in the range [0.1, 0.9].
MultiGridBarrier.stopping_inexact — Methodstopping_inexact(lambda_tol::T, theta::T) where {T}Create an inexact stopping criterion for Newton methods that combines Newton decrement and exact stopping conditions.
Arguments
lambda_tol: tolerance for the Newton decrement (type T).theta: tolerance parameter for the exact stopping criterion (type T).
Returns
A stopping criterion function with signature: stop(ymin, ynext, gmin, gnext, n, ndecmin, ndec) -> Bool
where:
ymin: minimum objective value seen so far.ynext: current objective value.gmin: minimum gradient norm seen so far.gnext: current gradient vector.n: current Newton direction.ndecmin: square root of minimum Newton decrement seen so far.ndec: square root of current Newton decrement (√(gᵀH⁻¹g)).
Algorithm
Returns true (stop) if either condition holds:
- Newton decrement condition:
ndec < lambda_tol - Exact stopping condition:
stopping_exact(theta)is satisfied
Notes
This criterion is "inexact" because it allows early termination based on the Newton decrement, which provides a quadratic convergence estimate. The Newton decrement λ = √(gᵀH⁻¹g) approximates the distance to the optimum in the Newton metric. Typical values: lambda_tol ∈ [1e-6, 1e-3], theta ∈ [0.1, 0.9].
PyPlot.plot — Functionplot(sol::AMGBSOL, k::Int=1; kwargs...)
plot(sol::ParabolicSOL, k::Int=1; kwargs...)
plot(M::Geometry, z::Vector; kwargs...)
plot(M::Geometry, ts::AbstractVector, U::Matrix; frame_time=..., embed_limit=..., printer=...)Visualize solutions and time sequences on meshes.
- 1D problems: Line plot. For spectral methods, you can specify evaluation points with
x=-1:0.01:1. - 2D FEM: Triangulated surface plot using the mesh structure.
- 2D spectral: 3D surface plot. You can specify evaluation grids with
x=-1:0.01:1, y=-1:0.01:1.
Time sequences (animation):
- Call
plot(M, ts, U; frame_time=1/30, printer=anim->nothing)whereUhas columns as frames andtsare absolute times in seconds (non-uniform allowed). - Or simply call
plot(sol)wheresolis aParabolicSOLreturned byparabolic_solve(usessol.ts). - Animation advances at a fixed frame rate given by
frame_time(seconds per video frame). For irregularts, each video frame shows the latest data frame with timestamp ≤ current video time. - The
printercallback receives the Matplotlib animation object; use it to display or save (e.g.,anim.save("out.mp4")). embed_limitcontrols the maximum embedded HTML5 video size in megabytes.
When sol is a solution object returned by amgb or the *_solve helpers, plot(sol,k) plots the kth component sol.z[:, k] using sol.geometry. plot(sol) uses the default k=1.
All other keyword arguments are passed to the underlying PyPlot functions.
Index
MultiGridBarrier.MultiGridBarrierMultiGridBarrier.AMGBConvergenceFailureMultiGridBarrier.ConvexMultiGridBarrier.FEM1DMultiGridBarrier.FEM2DMultiGridBarrier.GeometryMultiGridBarrier.SPECTRAL1DMultiGridBarrier.SPECTRAL2DBase.intersectMultiGridBarrier.amgbMultiGridBarrier.apply_DMultiGridBarrier.convex_Euclidian_powerMultiGridBarrier.convex_linearMultiGridBarrier.convex_piecewiseMultiGridBarrier.fem1dMultiGridBarrier.fem1d_solveMultiGridBarrier.fem2dMultiGridBarrier.fem2d_solveMultiGridBarrier.interpolateMultiGridBarrier.parabolic_solveMultiGridBarrier.spectral1dMultiGridBarrier.spectral1d_solveMultiGridBarrier.spectral2dMultiGridBarrier.spectral2d_solveMultiGridBarrier.stopping_exactMultiGridBarrier.stopping_inexactPyPlot.plot