Generate N2 diagram for the VDEF MDAO example.

This script creates an interactive HTML N2 diagram showing the system architecture and data flow for the plasma torch MDAO problem.

Usage:

python generate_n2_diagram.py

The diagram will open automatically in your default web browser.

import openmdao.api as om
from example_vdef_mdao import setup_problem_with_power_constraint


def generate_n2_diagram():
    """Generate N2 diagram for the MDAO problem.

    Creates an interactive HTML N2 diagram showing the connections
    between all subsystems and components in the torch design problem.
    The diagram is configured to show detailed node information by default.

    The model is run once with representative parameter values to populate
    all variables with realistic computed values for detailed inspection.
    """
    print("\n" + "=" * 70)
    print("  Generating N2 Diagram for VDEF MDAO Example")
    print("=" * 70)

    # Set up the problem
    prob = setup_problem_with_power_constraint()
    prob.setup()

    # Run the model once to populate values for better visualization
    print("\n  Setting parameter values and running model...")
    print("  (This populates all variables with computed values)")

    # Fixed parameters with units in comments
    prob.set_val("pulse_duration", 1e-6)  # s (1 µs HV pulse)
    prob.set_val("sustainer_voltage", 500.0)  # V
    prob.set_val("mass_flow", 160 / 86400)  # kg/s (converted from 160 kg/d)
    prob.set_val("gas_properties_pressure", 101325.0)  # Pa (atmospheric)
    prob.set_val("preheat_temperature", 300.0)  # K
    prob.set_val("electrode_radius", 0.005)  # m (5 mm)
    prob.set_val("graphite_sublimation_temp", 3900.0)  # K
    prob.set_val("graphite_heat_capacity", 710.0)  # J/(kg·K)
    prob.set_val("torch_length", 0.1)  # m (100 mm)
    prob.set_val("torch_diameter", 0.02)  # m (20 mm)

    # Design variables - representative mid-range values
    prob.set_val("pulse_frequency", 50000.0)  # Hz (50 kHz)
    prob.set_val("hv_voltage", 20000.0)  # V (20 kV)
    prob.set_val("gap_distance", 0.01)  # m (10 mm)

    # Run the model
    prob.run_model()

    print("\n  Model converged successfully!")
    print("  All variables now contain computed values.")

    # Generate N2 diagram with detailed information
    print("\n  Generating interactive N2 diagram...")
    om.n2(
        prob,
        outfile="n2_diagram.html",
        show_browser=True,
        title="Plasma Torch MDAO System - Detailed N2 Diagram",
    )

    print("\n" + "-" * 70)
    print("  N2 diagram generated successfully!")
    print("-" * 70)
    print("\n  Output file: n2_diagram.html")
    print("  The diagram should open in your default web browser.")

    print("\n  Interactive features:")
    print("  ---------------------")
    print("  - Click on any component to see detailed variable information")
    print("  - Hover over connections to see variable names and values")
    print("  - Use toolbar buttons to:")
    print("    * Toggle variable names visibility")
    print("    * Show/hide solver information")
    print("    * Zoom in/out or reset view")
    print("    * Search for specific components or variables")
    print("  - Click the info icon (?) in toolbar for help")

    print("\n  Key components to explore:")
    print("  --------------------------")
    print("  - TorchDesignGroup - Main physics model")
    print("  - balance - Solves for sustainer_pulse_duration")
    print("  - required_energy - Computes target energy per pulse from power")
    print("  - actual_energy - Computes actual energy per pulse")
    print("  - power_check - Validates power constraint is met")

    print("\n" + "=" * 70)


if __name__ == "__main__":
    try:
        generate_n2_diagram()
    except Exception as e:
        print(f"\nError: {e}")
        import traceback

        traceback.print_exc()