A remote session called at fixed design points
In one minuteThe calls an optimizer or MDO framework running on another machine would make on a warm session of a deployment — evaluate, gradients, adjoint and tangent products, a finite-difference cross-check, checkpoint and restore — shown at three fixed design points, with no optimizer.
examples/remote_session.py shows what an external driver calls on a remote Gyre
deployment. The script contains no optimizer and no loop that updates a design: it visits
three fixed design points and makes, at each, the calls a driver would make. Gyre, somewhere
on the network, evaluates the flow and returns exact derivatives; what to do with them is
the business of the caller.
.venv/bin/python examples/remote_session.py http://HOST:8600
HOST is the machine the deployment runs on (default http://127.0.0.1:8600). The client
needs the gyre package (for gyre.client) and NumPy; no flow is solved on the client.
- Opens a warm session on the preset
naca0012_eulerwithGyreClient(url).session(...)and prints the inputs (with units) and outputs the session declares (flow.describe()). - Reads the surface nodes (
flow.surface_coordinates()) and builds one smooth camber mode on them: a displacement field of the shape ofx_surface, zero at the leading and trailing edge. - Visits the design points
POINTS— (angle of attack in degrees, mode amplitude in chords) = (2.0, 0), (2.5, 0), (2.5, 2·10⁻³) — and at each calls
out = flow.evaluate(alpha_deg=alpha_deg, x_surface=amplitude * mode)
grad = flow.gradients(of=["cl", "cm"], wrt=["alpha_deg", "x_surface"])
It stops with an error if out["converged"] is false, and obtains the derivative with
respect to the amplitude by the chain rule of its own parameterisation: the sum of the
shape-sensitivity field grad[...]["x_surface"] times the mode.
4. At the last point, asks for products instead of whole gradients:
flow.adjoint({"cl": 1.0, "cm": -0.5}, wrt=["alpha_deg", "x_surface"]) (one transposed
solve for a weighted combination of outputs) and
flow.tangent({"x_surface": mode}, outputs=["cl", "cm"]) (one forward solve along the
mode), and prints both next to the values assembled from the gradients of step 3.
5. Cross-checks dcl/dalpha_deg against a central difference of two re-converged
evaluations at alpha_deg ± 0.01.
6. Takes a checkpoint (flow.checkpoint(), bytes), lets the session close, rebuilds it with
GyreClient.restore_session(blob), asks it for its status (flow.state()) and
re-evaluates: the restored session has the inputs and the converged state of the
original.
The forward product and the checkpoint are skipped, with a printed remark, on a deployment that answers 404 or 405 for those routes (one installed before they existed).
- The cost of a gradient does not grow with the number of shape variables. The derivative with respect to every surface node comes back as one field per output; projecting it on one mode or two hundred costs the client a sum.
- Units. The session takes and differentiates with respect to
alpha_deg(degrees); the in-process discipline would usealphain radians (outputs and units). - Warm starts. Each evaluation starts from the previous converged flow.
- Failures are data. If an evaluation does not converge,
evaluatereturnsconverged: falsewith areason; the script raises at that point rather than differentiating a state that is not a solution (MDO integration, Troubleshooting). - The mode, the design points and the chain rule are client code. Nothing in the service knows what the caller does with the numbers.