MultiGridBarrier 0.9.0

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
fem1d_solve(L=5,p=1.0,verbose=false);

A 2d p-Laplace problem:

fem2d_solve(L=3,p=1.0,verbose=false);

Spectral elements

Solve a 1d p-Laplace problem using spectral methods as follows:

spectral1d_solve(n=40,p=1.0,verbose=false);

A 2d p-Laplace problem:

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.

fem1d_solve(L=5,p=1.0,state_variables=[:u :dirichlet; :s :uniform],verbose=false);

Parabolic problems

A time-dependent problem:

parabolic_solve(h=0.1,L=3,printer=anim->anim.save("parabolic.mp4"),verbose=false);

Module reference

MultiGridBarrier.MultiGridBarrierModule
module MultiGridBarrier

Module MultiGridBarrier solves convex optimization problems in function spaces, for example, solving p-Laplace problems. We recommend to start with the functions fem1d_solve(), fem2d_solve(), spectral1d_solve(), spectral2d_solve(). These functions are sufficient to solve p-Laplace problems in 1d or 2d, using finite or spectral elements.

For more general use, the user will need to familiarize themselves with the basic ideas of convex optimization.

  • Overview of convex optimization in function spaces by MultiGrid Barrier method.

The general idea is to build a multigrid hierarchy, represented by an AMG object, and barrier for a convex set, represented by a Barrier object, and then solve a convex optimization problem using the amgb() solver.

To generate the multigrid hierarchy represented by the AMG object, use either fem1d(), fem2d(), spectral1d() or spectral2d() functions. These constructors will assemble suitable AMG objects for either FEM or spectral discretizations, in 1d or 2d. One should think of these four constructors as being specialized in constructing some specific function spaces. A user can use the amg() constructor directly if custom function spaces are required, but this is more difficult.

We now describe the barrier function.

Assume that $\Omega \subset \mathbb{R}^d$ is some open set. Consider the example of the p-Laplace problem on $\Omega$. Let $f(x)$ be a "forcing" (a function) on $\Omega$, and $1 \leq p < \infty$. One wishes to solve the minimization problem

\[\begin{equation} \inf_u \int_{\Omega} fu + \|\nabla u\|_2^p \, dx. \tag{1} \end{equation}\]

Generally speaking, $u$ will range in some function space, e.g. a space of differentiable functions satisfying homogeneous Dirichlet conditions. Under some conditions, minimizing (1) is equivalent to solving the p-Laplace PDE:

\[\nabla \cdot (\|\nabla u\|_2^{p-2}\nabla u) = {1 \over p} f.\]

We introduce the "slack function" $s(x)$ and replace (1) with the following equivalent problem:

\[\begin{equation} \inf_{s(x) \geq \|\nabla u(x)\|_2^p} \int_{\Omega} fu + s \, dx. \tag{2} \end{equation}\]

Define the convex set $\mathcal{Q} = \{ (u(x),q(x),s(x)) \; : \; s(x) \geq \|q(x)\|_2^p \}$, and

\[z = \begin{bmatrix} u \\ s \end{bmatrix}, \qquad c^T = [f,0,1], \qquad Dz = \begin{bmatrix} u \\ \nabla u \\ s \end{bmatrix}.\]

Then, (2) can be rewritten as

\[\begin{equation} \inf_{Dz \in \mathcal{Q}} \int_{\Omega} c^T(x)Dz(x) \, dx. \tag{3} \end{equation}\]

Recall that a barrier for $\mathcal{Q}$ is a convex function $\mathcal{F}$ on $\mathcal{Q}$ such that $\mathcal{F} < \infty$ in the interior of $\mathcal{Q}$ and $\mathcal{F} = \infty$ on the boundary of $\mathcal{Q}$. A barrier for the p-Laplace problem is:

\[\mathcal{F}(u,q,s) = \int_{\Omega} -\log(s^{2 \over p} - \|q\|_2^2) - 2\log s \, dx = \int_{\Omega} F(Dz(x)) \, dx.\]

The central path $z^*(t)$ minimizes, for each fixed $t>0$, the quantity

\[\int_{\Omega} tc^TDz + F(Dz) \, dx.\]

As $t \to \infty$, $z^*(t)$ forms a minimizing sequence (or filter) for (3). We think of the function $c(x)$ as the "functional" that we seek to minimize.

The Convex{T} type describes various convex sets (denoted $Q$ above) by way of functions barrier(), cobarrier() and slack(). barrier is indeed a barrier for $Q$, cobarrier() is a barrier for a related feasibility problems, and slack() is used in solving the feasibility problem. Convex{T} objects can be created using the various convex_...() constructors, e.g. convex_Euclidian_power() for the p-Laplace problem.

Once one has AMG and Convex objects, and a suitable "functional" c, one uses the amgb() function to solve the optimization problem by the MultiGrid Barrier method, a variant of the barrier method (or interior point method) that is quasi-optimal for sufficiently regular problems.

source

Types reference

MultiGridBarrier.AMGType
@kwdef struct AMG{T,M,Geometry}
    ...
end

Objects of this type should probably be assembled by the constructor amg().

A multigrid with L levels. Denote by l between 1 and L, a grid level. Fields are:

  • x::Matrix{T} the vertices of the fine grid.
  • w::Vector{T} corresponding quadrature weights.
  • R_fine::Array{M,1} an array of L matrices. The columns of R_fine[l] are basis functions for the function space on grid level l, interpolated to the fine grid.
  • R_coarse::Array{M,1} an array of L matrices. The columns of R_coarse[l] are basis functions for the function space on grid level l. Unlike R_fine[l], these basis functions are on grid level l, not interpolated to the fine grid.
  • D::Array{M,2} an array of differential operators. For example, if the barrier parameters are to be u,ux,s, with ux the derivative of u, then D[l,:] = [I,Dx,I], where Dx is a numerical differentiation operator on grid level l.
  • refine_u::Array{M,1} an array of L grid refinement matrices. If x[l] has n[l] vertices, then refine_u[l] is n[l+1] by n[l].
  • coarsen_u::Array{M,1} an array of L grid coarsening matrices. coarsen_u[l] is n[l] by n[l+1].
  • refine_z::Array{M,1} an array of L grid refining matrices for the "state vector" z. For example, if z contains the state functions u and s, then there are k=2 state functions, and refine_z[l] is k*n[l+1] by k*n[l].
  • coarsen_z::Array{M,1} an array of L grid coarsening matrices for the "state vector" z. coarsen_z[l] is k*n[l] by k*n[l+1].

These various matrices must satisfy a wide variety of algebraic relations. For this reason, it is recommended to use the constructor amg().

source
MultiGridBarrier.BarrierType
Barrier

A type for holding barrier functions. Fields are:

f0::Function
f1::Function
f2::Function

f0 is the barrier function itself, while f1 is its gradient and f2 is the Hessian.

source
MultiGridBarrier.ConvexType
struct Convex
    barrier::Function
    cobarrier::Function
    slack::Function
end

The Convex data structure represents a convex domain $Q$ implicitly by way of three functions. The barrier function is a barrier for $Q$. cobarrier is a barrier for the feasibility subproblem, and slack is a function that initializes a valid slack value for the feasibility subproblem. The various convex_ functions can be used to generate various convex domains.

These functions are called as follows: barrier(x,y). x is a vertex in a grid, as per the AMG object. y is some vector. For each fixed x variable, y -> barrier(x,y) defines a barrier for a convex set in y.

source

Functions reference

MultiGridBarrier.amgMethod
function amg(::Type{Geometry};
    x::Matrix{T},
    w::Vector{T},
    state_variables::Matrix{Symbol},
    D::Matrix{Symbol},
    subspaces::Dict{Symbol,Vector{M}},
    operators::Dict{Symbol,M},
    refine::Vector{M},
    coarsen::Vector{M},
    full_space=:full,
    id_operator=:id,
    feasibility_slack=:feasibility_slack,
    generate_feasibility=true) where {T,M,Geometry}

Construct an AMG object for use with the amgb solver. In many cases, this constructor is not called directly by the user. For 1d and 2d finite elements, use the fem1d() or fem2d(). For 1d and 2d spectral elements, use spectral1d() or spectral2d(). You use amg() directly if you are implementing your own function spaces.

The AMG object shall represent all L grid levels of the multigrid hierarchy. Parameters are:

  • x: the vertices of the fine grid.
  • w: the quadrature weights for the fine grid.
  • state_variables: a matrix of symbols. The first column indicates the names of the state vectors or functions, and the second column indicates the names of the corresponding subspaces. A typical example is: state_variables = [:u :dirichlet; :s :full]. This would define the solution as being functions named u(x) and s(x). The u function would lie in the space :dirichlet, presumably consisting of functions with homogeneous Dirichlet conditions. The s function would lie in the space :full, presumably being the full function space, without boundary conditions.
  • D: a matrix of symbols. The first column indicates the names of various state variables, and the second column indicates the corresponding differentiation operator(s). For example: D = [:u :id ; :u :dx ; :s :id]. This would indicate that the barrier should be called as F(x,y) with y = [u,ux,s], where ux denotes the derivative of u with respect to the space variable x.
  • subspaces: a Dict mapping each subspace symbol to an array of L matrices, e.g. for each l, subspaces[:dirichlet][l] is a matrix whose columns span the homogeneous Dirichlet subspace of grid level l.
  • operators: a Dict mapping each differential operator symbol to a matrix, e.g. operators[:id] is an identity matrix, while operators[:dx] is a numerical differentiation matrix, on the fine grid level L.
  • refine: an array of length L of matrices. For each l, refine[l] interpolates from grid level l to grid level l+1. refine[L] should be the identity, and coarsen[l]*refine[l] should be the identity.
  • coarsen: an array of length L of matrices. For each l, coarsen[l] interpolates or projects from grid level l+1 to grid level l. coarsen[L] should be the identity.
  • generate_feasibility: if true, amg() returns a pair M of AMG objects. M[1] is an AMG object to be used for the main optimization problem, while M[2] is an AMG object for the preliminary feasibility sub problem. In this case, amg() also needs to be provided with the following additional information: feasibility_slack is the name of a special slack variable that must be unique to the feasibility subproblem (default: :feasibility_slack); full_space is the name of the "full" vector space (i.e. no boundary conditions, default: :full); and id_operator is the name of the identity operator (default: :id).
source
MultiGridBarrier.amg_plotMethod
function amg_plot(M::AMG{T, Mat,FEM2D}, z::Vector{T}) where {T,Mat}

Plot a piecewise quadratic (plus cubic "bubble") solution z on the given mesh. Note that the solution is drawn as (linear) triangles, even though the underlying solution is piecewise cubic. To obtain a more accurate depiction, especially when the mesh is coarse, it would be preferable to apply a few levels of additional subdivision, so as to capture the curve of the quadratic basis functions.

source
MultiGridBarrier.amg_plotMethod
function amg_plot(M::AMG{T,Mat,SPECTRAL1D},y;x=Array(-1:T(0.01):1),rest...) where {T,Mat}

Plot a solution using pyplot.

  • M: a mesh.
  • x: x values where the solution should be evaluated and plotted.
  • y: the solution, to be interpolated at the given x values via spectral1d_interp.
  • rest... parameters are passed directly to pyplot.plot.
source
MultiGridBarrier.amg_plotMethod

function amg_plot(M::AMG{T,Mat,SPECTRAL2D},z::Vector{T};x=-1:T(0.01):1,y=-1:T(0.01):1,rest...) where {T,Mat}

Plot a 2d solution.

  • M a 2d mesh.
  • x, y should be ranges like -1:0.01:1.
  • z the solution to plot.
source
MultiGridBarrier.amg_solveMethod
amg_solve(::Type{T}=Float64;
          L::Integer=2,
          n=nothing,
          method=FEM1D,
          K=nothing,
          state_variables::Matrix{Symbol} = [:u :dirichlet;
                                             :s :full],
          dim::Integer = amg_dim(method),
          D::Matrix{Symbol} = default_D[dim],
          M = amg_construct(T, method;
                            L=L, n=n, K=K,
                            state_variables=state_variables, D=D),
          p::T = T(1.0),
          g::Union{Function, Matrix{T}} = default_g(T)[dim],
          f::Union{Function, Matrix{T}} = default_f(T)[dim],
          Q::Convex{T} = convex_Euclidian_power(T, idx=2:dim+2, p=x->p),
          show=true,
          return_details=false,
          rest...) where {T}

Convenience interface to the MultiGridBarrier module. This function builds a discretization and calls amgb with the appropriate defaults. For a quick start on p-Laplace problems, simply call:

amg_solve()

Keyword arguments

  • L=2 : number of times to subdivide the base mesh.
  • n : number of quadrature nodes along each axis (only for spectral methods). If set, L is ignored.
  • method=FEM1D : discretization method. One of FEM1D, FEM2D, SPECTRAL1D, SPECTRAL2D.
  • K : initial mesh (only relevant for FEM2D).
  • state_variables : symbolic description of solution components (default [:u :dirichlet; :s :full]).
  • dim : problem dimension (1 or 2). Used only to determine defaults for f, g, Q, and D.
  • D : differential operators (default depends on dim).
  • M : AMG hierarchy, constructed automatically unless supplied explicitly.
  • p=1.0 : parameter for the p-Laplace operator (used only if Q is not overridden).
  • g : boundary conditions. Either a function (evaluated at mesh points) or a matrix. Defaults depend on dim.
  • f : forcing / cost functional. Either a function (evaluated at mesh points) or a matrix. Defaults depend on dim.
  • Q : convex domain for the variational problem. Defaults to convex_Euclidian_power, matching p-Laplace problems.
  • show=true : if true, plot the computed solution.
  • return_details=false :
    • if false, return the solution z as a matrix.
    • if true, return the detailed named tuple from amgb.
  • rest... : any further keyword arguments are forwarded to amgb.

Defaults

The defaults for f, g, and D depend on the spatial dimension:

dim12
f(x)->T[0.5,0.0,1.0](x)->T[0.5,0.0,0.0,1.0]
g(x)->T[x[1],2](x)->T[x[1]^2+x[2]^2,100.0]
D[:u :id[:u :id
:u :dx:u :dx
:s :id]:u :dy
:s :id]

Returns

  • If return_details=false (default): the solution z (matrix).
  • If return_details=true: the full solution object from amgb, which includes fields like z, SOL_feasibility, and SOL_main.
source
MultiGridBarrier.amgbMethod
amgb(M::Tuple{AMG{T,Mat,Geometry}, AMG{T,Mat,Geometry}},
     f::Union{Function, Matrix{T}},
     g::Union{Function, Matrix{T}},
     Q::Convex;
     x::Matrix{T}=M[1].x,
     t=T(0.1),
     t_feasibility=t,
     verbose=true,
     return_details=false,
     stopping_criterion,
     line_search,
     finalize,
     logfile=devnull,
     rest...) where {T,Mat,Geometry}

Algebraic MultiGrid Barrier (AMGB) driver.

High-level wrapper around amgb_core that:

  1. Builds the initial guess z0 and cost functional c0 from g and f.
  2. Solves a feasibility subproblem on M[2] if needed.
  3. Solves the main optimization problem on M[1].
  4. Optionally reports progress and logs diagnostics.

Arguments

  • M: a tuple (M_main, M_feas) of AMG hierarchies.
    • M[1] encodes the main problem.
    • M[2] encodes the feasibility subproblem.
  • f: objective functional to minimize. May be a function (evaluated at rows of x) or a precomputed matrix.
  • g: boundary/initial data. May be a function (evaluated at rows of x) or a precomputed matrix.
  • Q: convex domain describing admissible states.

Keyword arguments

  • x: mesh/sample points where f and g are evaluated when they are functions (default: M[1].x).
  • t: initial barrier parameter for the main solve.
  • t_feasibility: initial barrier parameter for the feasibility solve.
  • verbose: show a progress bar if true.
  • return_details: if true, return detailed results from both solves.
  • stopping_criterion: stopping criterion for the Newton solver (has a default based on mesh parameters).
  • line_search: line search strategy (default: linesearch_backtracking).
  • finalize: finalization stopping criterion (default: stopping_exact(T(0.1))).
  • logfile: IO stream for logging (default: devnull).
  • rest...: additional keyword arguments forwarded to amgb_core (e.g., tolerances, other options).

Initialization

If f/g are functions, c0 and z0 are built by evaluating on each row of x:

m = size(M[1].x, 1)
for k in 1:m
    z0[k, :] .= g(x[k, :])
    c0[k, :] .= f(x[k, :])
end

If f/g are matrices, they are used directly (their shapes must match the discretization implied by M[1]).

Feasibility handling

The routine checks barrier admissibility. If any point is infeasible under Q, a feasibility problem is automatically constructed and solved on M[2] (using an internal slack augmentation and an early-stop criterion). If feasibility is already satisfied, this step is skipped.

Returns

If return_details == false (default):

  • returns z, an m × n matrix, where m = size(x,1) and n is the number of state variables in the discretization.

If return_details == true:

  • returns a named tuple (z, SOL_feasibility, SOL_main,log) where SOL_feasibility is nothing if no feasibility step was needed. The SOL_* objects are the detailed results returned by amgb_core. log is a string log of the iterations, useful for debugging purposes.

Errors

Throws AMGBConvergenceFailure if either the feasibility or main solve fails to converge.

source
MultiGridBarrier.amgb_coreMethod
amgb_core(B::Barrier,
          M::AMG{T,Mat,Geometry},
          x::Matrix{T},
          z::Array{T,1},
          c::Array{T,2};
          tol,
          t,
          maxit,
          kappa,
          early_stop,
          progress,
          c0,
          max_newton,
          finalize,
          printlog,
          args...) where {T,Mat,Geometry}

Algebraic MultiGrid Barrier (AMGB) method.

Arguments

  • B : a Barrier object.
  • M : an AMG hierarchy.
  • x : a matrix with the same number of rows as M.x. Typically x = M.x.
  • z : initial iterate, which must be admissible (B.f0(z) < ∞).
  • c : objective functional to minimize. Concretely, the method minimizes the integral of c .* (D*z) (with D the differential operator in M), subject to barrier feasibility.

Keyword arguments

  • tol : stopping tolerance; the method stops once 1/t < tol.
  • t : initial barrier parameter.
  • maxit : maximum number of barrier iterations.
  • kappa : initial step size multiplier for t. Adapted dynamically but never exceeds this initial value.
  • early_stop : function z -> Bool; if true, the iteration halts early (e.g. in feasibility mode).
  • progress : callback receiving a scalar in [0,1] for reporting progress (default: no-op).
  • c0 : base offset added to the objective (c0 + t*c).
  • max_newton : maximum Newton iterations per inner solve (default depends on problem data).
  • finalize : finalization stopping criterion for the last Newton solve.
  • printlog : logging function.
  • args... : extra keyword arguments passed to inner routines (amgb_phase1, amgb_step).

Returns

A named tuple SOL with fields:

  • z : the computed solution.
  • z_unfinalized: the solution before finalization.
  • c : the input functional.
  • its : iteration counts across levels and barrier steps.
  • ts : sequence of barrier parameters t.
  • kappas : step size multipliers used.
  • times : wall-clock timestamps of iterations.
  • M : the AMG hierarchy.
  • t_begin, t_end, t_elapsed : timing information.
  • passed : whether phase 1 succeeded.
  • c_dot_Dz : recorded values of ⟨c, D*z⟩ at each iteration.

Throws AMGBConvergenceFailure if convergence is not achieved.

source
MultiGridBarrier.barrierMethod
function barrier(F;
    F1=(x,y)->ForwardDiff.gradient(z->F(x,z),y),
    F2=(x,y)->ForwardDiff.hessian(z->F(x,z),y))

Constructor for barriers.

  • F is the actual barrier function. It should take parameters (x,y).
  • F1 is the gradient of F with respect to y.
  • F2 is the Hessian of F with respect to y.

By default, F1 and F2 are automatically generated by the module ForwardDiff.

A more specific description of the Barrier object is as follows. The function Barrier.f0 has parameters:

function Barrier.f0(z,x,w,c,R,D,z0)

Here, R is a matrix and D is an array of matrices; x is a matrix of quadrature nodes with weights w, and c is a matrix describing the functional we seek to minimize. The value of Barrier.f0 is given by:

        p = length(w)
        n = length(D)
        Rz = z0+R*z
        Dz = hcat([D[k]*Rz for k=1:n]...)
        y = [F(x[k,:],Dz[k,:]) for k=1:p]
        dot(w,y)+sum([dot(w.*c[:,k],Dz[:,k]) for k=1:n])

Thus, Barrier.f0 can be regarded as a quadrature approximation of the integral

\[\int_{\Omega} \left(\sum_{k=1}^nc_k(x)v_k(x)\right) + F(x,v_1(x),\ldots,v_n(x)) \, dx \text{ where } v_k = D_k(z_0 + Rz).\]

Functions Barrier.f1 and Barrier.f2 are the gradient and Hessian, respectively, of Barrier.f0, with respect to the z parameter. If the underlying matrices are sparse, then sparse arithmetic is used for Barrier.f2.

source
MultiGridBarrier.convex_Euclidian_powerMethod
function convex_Euclidian_power(::Type{T}=Float64;idx=Colon(),A::Function=(x)->I,b::Function=(x)->T(0),p::Function=x->T(2)) where {T}

Generate a Convex object corresponding to the convex set defined by $z[end] \geq \|z[1:end-1]\|_2^p$ where $z = A(x)*y[idx] .+ b(x)$.

source
MultiGridBarrier.convex_linearMethod
function convex_linear(::Type{T}=Float64;idx=Colon(),A::Function=(x)->I,b::Function=(x)->T(0)) where {T}

Generate a Convex structure corresponding to the convex domain A(x,k)*y[idx] .+ b(x,k) ≤ 0.

source
MultiGridBarrier.fem1dMethod

function fem1d(::Type{T}=Float64; L::Int=4, n=nothing, K=nothing, statevariables = [:u :dirichlet :s :full], D = [:u :id :u :dx :s :id], generatefeasibility=true) where {T}

Construct an AMG object for a 1d piecewise linear finite element grid. The interval is [-1,1]. Parameters are:

  • L: divide the interval into 2^L subintervals (L for Levels).
  • state_variables: the "state vector" consists of functions, by default this is u(x) and s(x), on the finite element grid.
  • D: the set of differential operators. The barrier function F will eventually be called with the parameters F(x,Dz), where z is the state vector. By default, this results in F(x,u,ux,s), where ux is the derivative of u.
  • generate_feasibility: if true, returns a pair M of AMG objects. M[1] is the AMG object for the main problem, and M[2] is for the feasibility subproblem.
source
MultiGridBarrier.fem1d_interpMethod
function fem1d_interp(x::Vector{T},
                  y::Vector{T},
                  t::T) where{T}

Interpolate a 1d piecewise linear function at the given t value. If u(xi) is the piecewise linear function such that u(x[k])=y[k] then this function returns u(t).

source
MultiGridBarrier.fem2dMethod
function fem2d(::Type{T}, L::Int, K::Matrix{T};
                state_variables = [:u :dirichlet
                                   :s :full],
                D = [:u :id
                     :u :dx
                     :u :dy
                     :s :id],
                generate_feasibility=true) where {T}

Construct an AMG object for a 2d finite element grid on the domain K with piecewise quadratic elements. Parameters are:

  • K: a triangular mesh. If there are n triangles, then K should be a 3n by 2 matrix of vertices. The first column of K represents x coordinates, the second column represents y coordinates.
  • L: number of refinement levels (L for Levels).
  • state_variables: the "state vector" consists of functions, by default this is u(x) and s(x), on the finite element grid.
  • D: the set of differential operators. The barrier function F will eventually be called with the parameters F(x,y,Dz), where z is the state vector. By default, this results in F(x,y,u,ux,uy,s), where (ux,uy) is the gradient of u.
  • generate_feasibility: if true, returns a pair M of AMG objects. M[1] is the AMG object for the main problem, and M[2] is for the feasibility subproblem.
source
MultiGridBarrier.illinoisMethod
function illinois(f,a::T,b::T;fa=f(a),fb=f(b),maxit=10000) where {T}

Find a root of f between a and b using the Illinois algorithm. If f(a)*f(b)>=0, returns b.

source
MultiGridBarrier.newtonMethod
newton(::Type{Mat},
       F0::Function,
       F1::Function,
       F2::Function,
       x::Array{T,1};
       maxit=10000,
       stopping_criterion=stopping_exact(T(0.1)),
       line_search=linesearch_illinois,
       printlog) where {T,Mat}

Damped Newton iteration for unconstrained minimization of a differentiable function.

Arguments

  • F0 : objective function.
  • F1 : gradient of F0.
  • F2 : Hessian of F0 (must return a matrix of type Mat).
  • x : starting point (vector of type T).

Keyword arguments

  • maxit : maximum number of iterations (default: 10,000).
  • stopping_criterion : user-defined predicate deciding when to stop. The default is stopping_exact(T(0.1)) which checks whether the objective decreased and the gradient norm fell sufficiently.
  • line_search : line search strategy (default: linesearch_illinois). The alternative is linesearch_backtracking.
  • printlog : logging function.

Notes

The iteration stops if the stopping_criterion is satisfied or if maxit iterations are exceeded.

source
MultiGridBarrier.parabolic_plotMethod
function parabolic_plot(method,M::AMG{T, Mat,Geometry}, U::Matrix{T}; 
    interval=200, embed_limit=200.0,
    printer=(animation)->display("text/html", animation.to_html5_video(embed_limit=embed_limit))) where {T,Mat,Geometry}

Animate the solution of the parabolic problem.

source
MultiGridBarrier.parabolic_solveMethod
function parabolic_solve(::Type{T}=Float64;
    method = FEM2D,
    state_variables = [:u  :dirichlet
                       :s1 :full
                       :s2 :full],
    dim = amg_dim(method),
    f1 = x->T(0.5),
    f_default = default_f_parabolic[dim],
    p = T(1),
    h = T(0.2),
    f = (t,x)->f_default(h*f1(x)-x[1+dim],T(0.5),h/p),
    g = default_g_parabolic[dim],
    D = default_D_parabolic[dim],
    L = 2,
    t0 = T(0),
    t1 = T(1),
    M = amg_construct(T,method,L=L,D=D,state_variables=state_variables),
    Q = (convex_Euclidian_power(;idx=[1,2+dim],p=x->T(2)) 
        ∩ convex_Euclidian_power(;idx=vcat(2:1+dim,3+dim),p=x->p)),
    verbose = true,
    show = true,
    interval = 200,
    printer=(animation)->display("text/html", animation.to_html5_video(embed_limit=200.0)),
    rest...) where {T}

Solves a parabolic (i.e. time-dependent) p-Laplace problem of the form:

\[u_t - \nabla \cdot (\|\nabla u\|_2^{p-2}\nabla u) = -f_1.\]

We use the implicit Euler scheme $u_t \approx (u_{k+1}-u_k)/h$ to arrive at:

\[u_{k+1} - h\nabla \cdot (\|\nabla u_{k+1}\|_2^{p-2}\nabla u_{k+1}) = u_k-hf_1.\]

According to the calculus of variation, we look for a weak solution minimizing

\[J(u) = \int_{\Omega}{1 \over 2} u^2 + h {1 \over p} \|\nabla u\|_2^p + (hf_1-u_k)u \, dx\]

We introduce the slack functions $s_1 \geq u^2$ and $s_2 \geq \|\nabla u\|_2^p$ and minimize instead

\[\int_{\Omega} {1 \over 2}s_1 + {h \over p} s_2 + (hf_1-u_k)u \, dx.\]

The canonical form is:

\[z = \begin{bmatrix} u \\ s_1 \\ s_2 \end{bmatrix} \qquad f^T = \left[hf_1-u_k,0,0,{1 \over 2},{h \over p}\right] \qquad Dz = \begin{bmatrix} u \\ u_x \\ u_y \\ s_1 \\ s_2 \end{bmatrix} \qquad g = \begin{bmatrix} g_1 \\ 0 \\ 0 \end{bmatrix}.\]

Here, $g_1$ encodes boundary conditions for $u$. Then we minimize:

\[\int_{\Omega} f^TDz\]

The named arguments rest... are passed verbatim to amg_solve.

source
MultiGridBarrier.spectral1dMethod
function spectral1d(::Type{T}=Float64; n=nothing, L::Integer=2,
                K=nothing,
                state_variables = [:u :dirichlet
                                   :s :full],
                D = [:u :id
                     :u :dx
                     :s :id],
                generate_feasibility=true) where {T}

Construct an AMG object for a 1d spectral grid of polynomials of degree n-1. See also fem1d for a description of the parameters state_variables and D.

source
MultiGridBarrier.spectral1d_interpMethod
function spectral1d_interp(MM::AMG{T,Mat,SPECTRAL1D}, y::Vector{T},x) where {T,Mat}

A function to interpolate a solution y at some point(s) x.

  • MM the mesh of the solution.
  • y the solution.
  • x point(s) at which the solution should be evaluated.
source
MultiGridBarrier.spectral2dMethod

function spectral2d(::Type{T}=Float64; n=nothing, L::Integer=2, K=nothing, statevariables = [:u :dirichlet :s :full], D = [:u :id :u :dx :u :dy :s :id], generatefeasibility=true) where {T}

Construct an AMG object for a 2d spectral grid of degree n-1. See also fem2d for a description of state_variables and D.

source
MultiGridBarrier.spectral2d_interpMethod

function spectral2d_interp(MM::AMG{T,Mat,SPECTRAL2D},z::Vector{T},x::Matrix{T}) where {T,Mat}

Interpolate a solution z at point(s) x, given the mesh MM. See also spectral1d_interp.

source
MultiGridBarrier.stopping_exactMethod
stopping_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:

  1. No objective improvement: ynext ≥ ymin
  2. 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].

source
MultiGridBarrier.stopping_inexactMethod
stopping_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:

  1. Newton decrement condition: ndec < lambda_tol
  2. 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].

source

Index