GUI Documentation#

The ZEFIR GUI provides an interactive environment for creating and visualizing potential flows.

Architecture#

The GUI is built with a modular architecture using PySide6:

  • Main Window (main_window.py): Top-level window with dockable panels

  • Plot Widget (plot_widget.py): Matplotlib embedded widget for visualization

  • Flow Manager (flow_widgets.py): Controls for adding/editing flows

  • Visualization Panel (visualization_panel.py): Display options and settings

  • Log Console (log_widget.py): Real-time log display with level filtering

Components#

Main Window#

Plot Widget#

Flow Widgets#

Visualization Panel#

Log Console#

The log console provides:

  • Real-time logging: Displays log messages as they are generated

  • Level filtering: Filter by Debug, Info, Warning, Error, or Critical

  • Color coding: Different colors for different log levels

  • Monospace font: Easy to read log messages

Entry Point#

The GUI can be launched via the CLI or programmatically:

CLI Entry Point:

Parser Configuration:

Programmatic Launch:

Flow Metadata System#

Each flow class includes metadata that enables automatic GUI generation:

class zefir.potential.flows.base.FlowMetadata(name, parameters, has_position=False)[source]#

Bases: object

Metadata for a flow type to enable automatic GUI generation.

This class stores information about flow parameters including their types, default values, ranges, and labels for GUI widget generation.

Parameters:
  • name (str) – Display name for the flow type in the GUI

  • parameters (dict) – Dictionary of parameter definitions where keys are parameter names and values are dicts with keys: type, default, min, max, labels (optional)

  • has_position (bool) – Whether the flow has a position parameter that can be set via mouse click

Examples

>>> from zefir.typing import ParamType
>>> metadata = FlowMetadata(
...     "Source Flow",
...     {
...         "flow_rate": {"type": ParamType.FLOAT, "default": 1.0, "min": -100, "max": 100},
...         "center": {"type": ParamType.VECTOR2, "default": [0.0, 0.0], "min": -10, "max": 10}
...     },
...     has_position=True
... )
__init__(name, parameters, has_position=False)[source]#

Example: Adding a New Flow Type#

To add a new flow type:

  1. Create a new module in zefir/potential/flows/

  2. Define the flow class with metadata:

class MyNewFlow(ComplexPotential):
    metadata = FlowMetadata(
        "My Flow Name",
        {
            "parameter1": {
                "type": "float",
                "default": 1.0,
                "min": 0,
                "max": 10
            }
        },
        has_position=True
    )

    def __init__(self, parameter1, center):
        self._param1 = parameter1
        self._center = complex(*center)

    def __call__(self, z, deriv=0):
        # Implement your flow
        pass
  1. Import it in zefir/potential/flows/__init__.py

  2. Add to FLOW_TYPES in FlowListManager

The GUI will automatically create appropriate input widgets based on the metadata.

Extending the GUI#

To add a new GUI application (e.g., for a different physics module):

  1. Create a new package in zefir/gui/ (e.g., zefir/gui/aero/)

  2. Implement get_parser() and run_from_args() in __init__.py:

def get_parser() -> argparse.ArgumentParser:
    """Return argument parser for this GUI."""
    parser = argparse.ArgumentParser(
        description="Launch the aero GUI"
    )
    parser.add_argument(
        "--log-level",
        choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
        default="INFO",
        help="Set the logging level"
    )
    return parser

def run_from_args(args: argparse.Namespace) -> int:
    """Run the GUI with parsed arguments."""
    configure_log(level=getattr(LogLevel, args.log_level))
    # Launch your GUI
    return 0
  1. Update zefir/__main__.py to discover your new GUI:

import zefir.gui.aero as aero_gui
guis["aero"] = (aero_gui.get_parser, aero_gui.run_from_args)

Your new GUI will then be accessible via python -m zefir aero.