optimize.Optimization

optimize.Optimization(
    name,
    objective=None,
    of=None,
    study=None,
    metric=None,
    *,
    regularizer=None,
    regularizer_weight=0.0,
    remesh_every=None,
    gradient_path=GradientPath.DIRECT,
    steps=30,
    learning_rate=0.05,
    method=OptimizerMethod.ADAM,
    precision=Precision.SINGLE,
)

Declarative gradient-based optimization of a scene’s free parameters.

Attributes

Name Type Description
name str Optimization identifier (unique within a scene program).
objective Callable[[dict[str, Any]], Any] | None Callable (params: dict) -> scalar — a JAX-traceable function of the free-parameter dict, minimized by :meth:run (objective form; leave None for the study form).
of Any The scene object whose FREE parameters are optimized (anything :func:cadjoint.extract_parameters accepts; objective form only).
study Any A declared :class:~cadjoint.fem.study.ThermalStudy / :class:~cadjoint.fem.study.ElasticStudy (or its name) whose solved field the run minimizes (study form; mutually exclusive with objective/of).
metric ObjectiveMetricLike | None Study-form objective — a :class:~cadjoint.enums.ObjectiveMetric or its plain string spelling: "mean" or "max" of the result’s objective scalar (temperature / displacement magnitude), or "compliance" (traction work, twice the strain energy; elastic studies only).
regularizer Callable[[dict[str, Any]], Any] | None Optional callable (params: dict) -> scalar added to the study metric as regularizer_weight * regularizer, e.g. a smoothed material volume (study form, keyword-only).
regularizer_weight float Weight of the regularizer term (keyword-only).
remesh_every int | None Study form: re-extract the frozen mesh topology at the current design every this many steps (0: never; default 6). In between, only node positions move — differentiably.
gradient_path GradientPathLike Study form: how the design->points derivative is carried per step (keyword-only) — a :class:~cadjoint.enums.GradientPath or its plain string spelling, normalised (aliases resolved) on construction. "direct" (default) is the validated frozen-topology path — node positions Newton re-projected onto the true SDF, solved in-process. "tesseract" runs the packaged two-tesseract chain instead (lattice samples -> mesher tesseract with its surface-interpolation VJP -> solver tesseract adjoint); it meshes the trilinear interpolant of the samples, so it can need a finer lattice than the direct path and its gradient carries only normal boundary motion (measured in research/tet-vs-hex.md). "tesseract-dc" is the narrow cut: dual contouring stays in JAX on the true SDF and only TetGen is wrapped (tetfill tesseract, exact pass-through VJP on the vertices -Y preserves), so it meshes the same geometry the direct path does — tet SimMesh only. Both chain paths resolve each stage through :mod:cadjoint.plugins, so where the mesher and the solver actually run is configuration (plugins.toml), and both spellings accept the aliases "plugins" / "plugins-dc". Both require the tesseract extra. The final reported result is always evaluated on the direct path.
steps int Default number of optimizer steps (keyword-only).
learning_rate float Optimizer step size (keyword-only).
method OptimizerMethodLike A :class:~cadjoint.enums.OptimizerMethod or its plain string spelling — "adam" (default) or "sgd" (keyword-only). Runs through optax; plain gradient descent when optax is missing.
precision PrecisionLike A :class:~cadjoint.enums.Precision or its plain string spelling, "single" (default) or "double" (keyword-only). "double" holds jax_enable_x64 for the whole of :meth:run and restores it afterwards. An objective whose solver needs float64 needs this, and a scope inside the solver is not enough: :func:cadjoint.flow.precision.double_precision covers the forward pass, but :func:jax.grad runs the transposed pass after that scope has closed, and a float32 process cannot then materialise the float64 intermediates the forward built (lax.dynamic_update_slice requires arguments to have the same dtypes, got float32, float64). Declaring it here rather than flipping the flag at a scene’s module scope is what keeps the scene itself float32 for the WGSL shader, which has no f64 – so a scene carrying a flow optimization still opens in the viewer, and the viewer can still run it.

Methods

Name Description
describe JSON-ready payload: everything the viewer needs to display it.
run Minimize the objective over the target’s free parameters.

describe

optimize.Optimization.describe(scene=None)

JSON-ready payload: everything the viewer needs to display it.

Parameters

Name Type Description Default
scene Any Optional scene object; lets a study-backed optimization whose study meshes the whole scene report the scene’s free parameters (the compile worker passes it). None

run

optimize.Optimization.run(steps=None, callback=None, *, scene=None)

Minimize the objective over the target’s free parameters.

Pure reverse-mode differentiation (:func:jax.value_and_grad) through the objective. Objective-form runs never touch the scene object; study-backed runs restore the target’s original parameter values before returning (topology refreezes write the candidate design into the target while extracting) — the returned run carries the optimized values either way.

Parameters

Name Type Description Default
steps int | None Number of optimizer steps (default: the declared steps). None
callback Optional callback(record) invoked with each history record as it is produced. None
scene Any Study form only — the scene object the study meshes, required when neither the study nor its SimMesh declares a domain (keyword-only; ignored by the objective form). None

Returns

Name Type Description
OptimizationRun The finished :class:OptimizationRun. Study-backed runs also
OptimizationRun carry the final design’s concrete result, solved on a
OptimizationRun freshly extracted mesh.

Raises

Name Type Description
ValueError When the target has no free parameters, the objective (or its gradient) leaves the finite range, or a study-backed run cannot resolve its target.