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.MultiGridBarrier
— Modulemodule 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.
Types reference
MultiGridBarrier.AMG
— Type@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 ofL
matrices. The columns ofR_fine[l]
are basis functions for the function space on grid levell
, interpolated to the fine grid.R_coarse::Array{M,1}
an array ofL
matrices. The columns ofR_coarse[l]
are basis functions for the function space on grid levell
. UnlikeR_fine[l]
, these basis functions are on grid levell
, not interpolated to the fine grid.D::Array{M,2}
an array of differential operators. For example, if the barrier parameters are to beu,ux,s
, withux
the derivative ofu
, thenD[l,:] = [I,Dx,I]
, whereDx
is a numerical differentiation operator on grid levell
.refine_u::Array{M,1}
an array ofL
grid refinement matrices. Ifx[l]
hasn[l]
vertices, thenrefine_u[l]
isn[l+1]
byn[l]
.coarsen_u::Array{M,1}
an array ofL
grid coarsening matrices.coarsen_u[l]
isn[l]
byn[l+1]
.refine_z::Array{M,1}
an array ofL
grid refining matrices for the "state vector"z
. For example, ifz
contains the state functionsu
ands
, then there arek=2
state functions, andrefine_z[l]
isk*n[l+1]
byk*n[l]
.coarsen_z::Array{M,1}
an array ofL
grid coarsening matrices for the "state vector"z
.coarsen_z[l]
isk*n[l]
byk*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()
.
MultiGridBarrier.Barrier
— TypeBarrier
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.
MultiGridBarrier.Convex
— Typestruct 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
.
MultiGridBarrier.FEM1D
— Typeabstract type FEM1D end
MultiGridBarrier.FEM2D
— Typeabstract type FEM2D end
MultiGridBarrier.SPECTRAL1D
— Typeabstract type SPECTRAL1D end
MultiGridBarrier.SPECTRAL2D
— Typeabstract type SPECTRAL2D end
Functions reference
MultiGridBarrier.amg
— Methodfunction 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 asF(x,y)
withy = [u,ux,s]
, whereux
denotes the derivative ofu
with respect to the space variablex
.subspaces
: aDict
mapping each subspace symbol to an array ofL
matrices, e.g. for eachl
,subspaces[:dirichlet][l]
is a matrix whose columns span the homogeneous Dirichlet subspace of grid levell
.operators
: aDict
mapping each differential operator symbol to a matrix, e.g.operators[:id]
is an identity matrix, whileoperators[:dx]
is a numerical differentiation matrix, on the fine grid levelL
.refine
: an array of lengthL
of matrices. For eachl
,refine[l]
interpolates from grid levell
to grid levell+1
.refine[L]
should be the identity, andcoarsen[l]*refine[l]
should be the identity.coarsen
: an array of lengthL
of matrices. For eachl
,coarsen[l]
interpolates or projects from grid levell+1
to grid levell
.coarsen[L]
should be the identity.generate_feasibility
: if true,amg()
returns a pairM
ofAMG
objects.M[1]
is anAMG
object to be used for the main optimization problem, whileM[2]
is anAMG
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
); andid_operator
is the name of the identity operator (default::id
).
MultiGridBarrier.amg_construct
— Methodamg_construct(::Type{T},::Type{FEM1D};rest...) where {T} = fem1d(T;rest...)
MultiGridBarrier.amg_construct
— Methodamg_construct(::Type{T},::Type{FEM2D};rest...) where {T} = fem2d(T;rest...)
MultiGridBarrier.amg_construct
— Methodamg_construct(::Type{T},::Type{SPECTRAL1D};rest...) where {T} = spectral1d(T;rest...)
MultiGridBarrier.amg_construct
— Methodamg_construct(::Type{T},::Type{SPECTRAL2D},L,n,K) where {T} = spectral2d(T,n=n,L=L)
MultiGridBarrier.amg_dim
— Methodamg_dim(::Type{FEM1D}) = 1
MultiGridBarrier.amg_dim
— Methodamg_dim(::Type{FEM2D}) = 2
MultiGridBarrier.amg_dim
— Methodamg_dim(::Type{SPECTRAL1D}) = 1
MultiGridBarrier.amg_dim
— Methodamg_dim(::Type{SPECTRAL2D}) = 2
MultiGridBarrier.amg_plot
— Methodamg_plot(M::AMG{T,Mat,FEM1D}, z::Vector{T}) where {T,Mat} = plot(M.x[end],z)
MultiGridBarrier.amg_plot
— Methodfunction 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.
MultiGridBarrier.amg_plot
— Methodfunction 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 givenx
values viaspectral1d_interp
.rest...
parameters are passed directly topyplot.plot
.
MultiGridBarrier.amg_plot
— Methodfunction 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.
MultiGridBarrier.amg_solve
— Methodamg_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 ofFEM1D
,FEM2D
,SPECTRAL1D
,SPECTRAL2D
.K
: initial mesh (only relevant forFEM2D
).state_variables
: symbolic description of solution components (default[:u :dirichlet; :s :full]
).dim
: problem dimension (1 or 2). Used only to determine defaults forf
,g
,Q
, andD
.D
: differential operators (default depends ondim
).M
: AMG hierarchy, constructed automatically unless supplied explicitly.p=1.0
: parameter for the p-Laplace operator (used only ifQ
is not overridden).g
: boundary conditions. Either a function (evaluated at mesh points) or a matrix. Defaults depend ondim
.f
: forcing / cost functional. Either a function (evaluated at mesh points) or a matrix. Defaults depend ondim
.Q
: convex domain for the variational problem. Defaults toconvex_Euclidian_power
, matching p-Laplace problems.show=true
: iftrue
, plot the computed solution.return_details=false
:- if
false
, return the solutionz
as a matrix. - if
true
, return the detailed named tuple fromamgb
.
- if
rest...
: any further keyword arguments are forwarded toamgb
.
Defaults
The defaults for f
, g
, and D
depend on the spatial dimension:
dim | 1 | 2 |
---|---|---|
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 solutionz
(matrix). - If
return_details=true
: the full solution object fromamgb
, which includes fields likez
,SOL_feasibility
, andSOL_main
.
MultiGridBarrier.amgb
— Methodamgb(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:
- Builds the initial guess
z0
and cost functionalc0
fromg
andf
. - Solves a feasibility subproblem on
M[2]
if needed. - Solves the main optimization problem on
M[1]
. - Optionally reports progress and logs diagnostics.
Arguments
M
: a tuple(M_main, M_feas)
ofAMG
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 ofx
) or a precomputed matrix.g
: boundary/initial data. May be a function (evaluated at rows ofx
) or a precomputed matrix.Q
: convex domain describing admissible states.
Keyword arguments
x
: mesh/sample points wheref
andg
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 iftrue
.return_details
: iftrue
, 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 toamgb_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
, anm × n
matrix, wherem = size(x,1)
andn
is the number of state variables in the discretization.
If return_details == true
:
- returns a named tuple
(z, SOL_feasibility, SOL_main,log)
whereSOL_feasibility
is nothing if no feasibility step was needed. TheSOL_*
objects are the detailed results returned byamgb_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.
MultiGridBarrier.amgb_core
— Methodamgb_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
: aBarrier
object.M
: anAMG
hierarchy.x
: a matrix with the same number of rows asM.x
. Typicallyx = M.x
.z
: initial iterate, which must be admissible (B.f0(z) < ∞
).c
: objective functional to minimize. Concretely, the method minimizes the integral ofc .* (D*z)
(withD
the differential operator inM
), subject to barrier feasibility.
Keyword arguments
tol
: stopping tolerance; the method stops once1/t < tol
.t
: initial barrier parameter.maxit
: maximum number of barrier iterations.kappa
: initial step size multiplier fort
. Adapted dynamically but never exceeds this initial value.early_stop
: functionz -> Bool
; iftrue
, 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 parameterst
.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.
MultiGridBarrier.apply_D
— Methodapply_D(D,z) = hcat([D[k]*z for k in 1:length(D)]...)
MultiGridBarrier.barrier
— Methodfunction 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 ofF
with respect toy
.F2
is the Hessian ofF
with respect toy
.
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
.
MultiGridBarrier.convex_Euclidian_power
— Methodfunction 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)$.
MultiGridBarrier.convex_linear
— Methodfunction 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.
MultiGridBarrier.fem1d
— Methodfunction 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 isu(x)
ands(x)
, on the finite element grid.D
: the set of differential operators. The barrier functionF
will eventually be called with the parametersF(x,Dz)
, wherez
is the state vector. By default, this results inF(x,u,ux,s)
, whereux
is the derivative ofu
.generate_feasibility
: iftrue
, returns a pairM
ofAMG
objects.M[1]
is theAMG
object for the main problem, andM[2]
is for the feasibility subproblem.
MultiGridBarrier.fem1d_interp
— Methodfunction 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)
.
MultiGridBarrier.fem1d_interp
— Methodfunction fem1d_interp(x::Vector{T},
y::Vector{T},
t::Vector{T}) where{T}
Returns [fem1d_interp(x,y,t[k]) for k=1:length(t)]
.
MultiGridBarrier.fem1d_solve
— Methodfem1d_solve(::Type{T}=Float64;rest...) where {T} = amg_solve(T;method=FEM1D,rest...)
MultiGridBarrier.fem2d
— Methodfunction 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 aren
triangles, thenK
should be a 3n by 2 matrix of vertices. The first column ofK
representsx
coordinates, the second column representsy
coordinates.L
: number of refinement levels (L for Levels).state_variables
: the "state vector" consists of functions, by default this isu(x)
ands(x)
, on the finite element grid.D
: the set of differential operators. The barrier functionF
will eventually be called with the parametersF(x,y,Dz)
, wherez
is the state vector. By default, this results inF(x,y,u,ux,uy,s)
, where(ux,uy)
is the gradient ofu
.generate_feasibility
: iftrue
, returns a pairM
ofAMG
objects.M[1]
is theAMG
object for the main problem, andM[2]
is for the feasibility subproblem.
MultiGridBarrier.fem2d_solve
— Methodfem2d_solve(::Type{T}=Float64;rest...) where {T} = amg_solve(T;method=FEM2D,rest...)
MultiGridBarrier.illinois
— Methodfunction 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
.
MultiGridBarrier.newton
— Methodnewton(::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 ofF0
.F2
: Hessian ofF0
(must return a matrix of typeMat
).x
: starting point (vector of typeT
).
Keyword arguments
maxit
: maximum number of iterations (default: 10,000).stopping_criterion
: user-defined predicate deciding when to stop. The default isstopping_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 islinesearch_backtracking
.printlog
: logging function.
Notes
The iteration stops if the stopping_criterion
is satisfied or if maxit
iterations are exceeded.
MultiGridBarrier.parabolic_plot
— Methodfunction 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.
MultiGridBarrier.parabolic_solve
— Methodfunction 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
.
MultiGridBarrier.spectral1d
— Methodfunction 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
.
MultiGridBarrier.spectral1d_interp
— Methodfunction 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.
MultiGridBarrier.spectral1d_solve
— Methodspectral1d_solve(::Type{T}=Float64;rest...) where {T} = amg_solve(T;method=SPECTRAL1D,rest...)
MultiGridBarrier.spectral2d
— Methodfunction 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
.
MultiGridBarrier.spectral2d_interp
— Methodfunction 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
.
MultiGridBarrier.spectral2d_solve
— Methodspectral2d_solve(::Type{T}=Float64;rest...) where {T} = amg_solve(T;method=SPECTRAL2D,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]
.
Index
MultiGridBarrier.MultiGridBarrier
MultiGridBarrier.AMG
MultiGridBarrier.Barrier
MultiGridBarrier.Convex
MultiGridBarrier.FEM1D
MultiGridBarrier.FEM2D
MultiGridBarrier.SPECTRAL1D
MultiGridBarrier.SPECTRAL2D
MultiGridBarrier.amg
MultiGridBarrier.amg_construct
MultiGridBarrier.amg_construct
MultiGridBarrier.amg_construct
MultiGridBarrier.amg_construct
MultiGridBarrier.amg_dim
MultiGridBarrier.amg_dim
MultiGridBarrier.amg_dim
MultiGridBarrier.amg_dim
MultiGridBarrier.amg_plot
MultiGridBarrier.amg_plot
MultiGridBarrier.amg_plot
MultiGridBarrier.amg_plot
MultiGridBarrier.amg_solve
MultiGridBarrier.amgb
MultiGridBarrier.amgb_core
MultiGridBarrier.apply_D
MultiGridBarrier.barrier
MultiGridBarrier.convex_Euclidian_power
MultiGridBarrier.convex_linear
MultiGridBarrier.fem1d
MultiGridBarrier.fem1d_interp
MultiGridBarrier.fem1d_interp
MultiGridBarrier.fem1d_solve
MultiGridBarrier.fem2d
MultiGridBarrier.fem2d_solve
MultiGridBarrier.illinois
MultiGridBarrier.newton
MultiGridBarrier.parabolic_plot
MultiGridBarrier.parabolic_solve
MultiGridBarrier.spectral1d
MultiGridBarrier.spectral1d_interp
MultiGridBarrier.spectral1d_solve
MultiGridBarrier.spectral2d
MultiGridBarrier.spectral2d_interp
MultiGridBarrier.spectral2d_solve
MultiGridBarrier.stopping_exact
MultiGridBarrier.stopping_inexact