A flexible optimization framework for Morpho, intended to replace the built-in optimize package in Morpho 0.6. It supports unconstrained and constrained shape optimization on meshes and fields, with a composable adapter architecture and a range of optimization algorithms.
This package can be installed with the morphopm package manager. Run
morphopm install optimize4
from the Terminal app.
The usual workflow is: define an OptimizationProblem, wrap it in a ProblemAdapter, and run an OptimizationController.
import optimize4
import meshtools
// Mesh and problem
var mesh = LineMesh(fn (t) [2*cos(t), sin(t)], -Pi...Pi:Pi/20, closed=true)
var problem = OptimizationProblem(mesh)
problem.addEnergy(Length())
problem.addConstraint(AreaEnclosed())
// Optimize
var adapter = ProblemAdapter(problem, mesh)
var opt = SQPController(adapter)
opt.optimize(500)
For unconstrained problems, use LBFGSController instead of SQPController.
A fuller version of the loop example (fixed enclosed area, minimal perimeter) lives in test/examples/loop.morpho; test/sqp/loop.morpho shows it solved with SQP.
Three layers work together:
| Layer | Role |
|---|---|
OptimizationProblem |
Describes energies and constraints using Morpho functionals |
OptimizationAdapter |
Uniform interface: parameters, objective, gradients, constraints. Adapters can be chained (penalty, fixing variables, caching, etc.) |
OptimizationController |
Implements an algorithm (L-BFGS, SQP, PGD, …) using only the adapter interface |
This separation lets algorithms stay independent of meshes and functionals, and lets you transform problems (e.g. penalty methods, Lagrange multipliers) without rewriting the solver.
| Problem | Recommended controller | Notes |
|---|---|---|
| Unconstrained | LBFGSController |
Default for mesh/field problems; scales to large DOF counts |
| Equality / inequality constraints | SQPController |
Primary constrained solver; L-BFGS Hessian + active-set KKT |
| Constrained, feasibility emphasis | ProjectedGradientDescentController |
Gradient projection + reprojection each step |
| Constrained, simple outer loop | PenaltyController |
Repeated unconstrained solves with increasing penalty |
| Small black-box test functions | FunctionAdapter + LBFGSController or SQPController |
Analytical or finite-difference derivatives |
| Education / debugging | GradientDescentController, LineSearchController |
Fixed step or Armijo line search |
Constrained controllers require constraints on the adapter (via addConstraint / addLocalConstraint). Unconstrained controllers will error if constraints are present unless you wrap the adapter (e.g. PenaltyAdapter, DeconstrainAdapter).
Reference problems live under test/examples/ (loop, thomson, cholesteric, nematic, tactoid, qtensor, …). The same problems are exercised under test/sqp/, test/pgd/, and test/penalty/ with different controllers.
See test/README.md for the automated test runner, CI directives, and layout.
In-package help is in share/help/optimize4.md (available through Morpho's help system after installation). It documents all public classes, adapters, and controllers.
A longer manual is in docs/manual.lyx (LyX source).
This package is experimental. The API and algorithms are still evolving ahead of the Morpho 0.6 release. Feedback and bug reports are welcome via GitHub issues.