Skip to content

[FEATURE] Add named load quantities to Airplane and Panel #262

Description

@camUrban

Problem Statement

The output modules negate the wind axes x and z force components so they read as induced drag and lift, and that sign rule is written out at 14 sites across the three output modules: twice in _output_rendering.get_scalars, twice each in plot_results_versus_time's forces and force coefficients figures, four times in its loads CSV assembly, and four times in log_results's value column. Every one of those sites re-derives a named physical quantity from a raw component vector, which is knowledge that belongs with the loads rather than with the code that displays them.

The scalar type vocabulary has the same problem at a smaller scale: the strings "induced drag", "side force", and "lift" are spelled out in eight places, namely the identical validation tuples in draw and animate, a third membership test in draw, the three branches in get_scalars, and four docstrings.

Location(s): pterasoftware/output.py, pterasoftware/_output_rendering.py, pterasoftware/geometry/airplane.py, pterasoftware/_panel.py

Proposed Solution

The fix has to reach two levels, because an Airplane-only fix would leave get_scalars untouched:

  1. Airplane already carries forces_W and forceCoefficients_W, so it gains named forces and named force coefficients. This covers the 12 sites in plot_results_versus_time and log_results. These attributes are additions to the public API.
  2. Panel gains named forces only. A coefficient needs the freestream dynamic pressure, which is a per-step quantity that reaches get_scalars as an argument rather than living on the Panel, so Panel cannot gain coefficient attributes. get_scalars keeps its division while losing its negation, reading, for example, this_panel.inducedDrag_W / qInf__E / this_panel.area. Because a Panel exists per mesh cell, the new attributes should be computed properties following the lazy caching pattern the class already uses rather than new slots. Unlike the Airplane additions, these are not additions to the public API: Panel is a private class, and while its instances are technically reachable through public attributes such as Wing.panels, that reachability is not by design, so the new properties carry no stability promise.
  3. Fold the scalar type vocabulary and the sign rule into one table in _output_rendering.py, so the validation tuples, the membership tests, the get_scalars branches, and the docstrings all reference a single source.
  4. Define the named wind axes force components in docs/AXES_POINTS_AND_FRAMES.md, so the mapping from forces_W to induced drag, side force, and lift, including the sign convention, is documented with the rest of the axes, points, and frames definitions rather than living only in code.

Additional Context

Nothing outside the output modules re-derives a named load quantity by flipping a sign, so the change is confined to the two loads classes and the output modules.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or requestmaintenanceImprovements or additions to documentation, testing, robustness, or tooling

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions