shell.Solution
shell.Solution(network, problem, result)Converged mean-flow result with named edge-field access.
Key methods
field(name), edge(e) Read a per-edge field across the network, or every field on one edge. print_states(), table() Show / return the full per-edge mean-flow state table. residuals(), print_residuals() The converged residual broken down equation-by-equation. composite(key), composites Read a composite element’s hidden interior (e.g. an orifice throat). species(e), mixture_fractions(e), marker(e) Per-edge chemistry: solved species, transported feed fractions, burnt marker. cuton_report() Per-duct plane-wave validity ceiling (higher-order-mode cut-on). eigenmodes(), forced_response(), perturbation_response(), nyquist_stability() Linear acoustic and stability analyses on this mean flow (see :mod:nefes.perturbation). to_yaml(path) Write the network and these results to a UI-readable YAML case.
Attributes
| Name | Description |
|---|---|
| composites | Every composite element in the network, as :class:CompositeView projections. |
| converged | Whether the solver reached the convergence tolerance. |
| elapsed | Seconds the mean-flow solve took, on a monotonic clock. |
| iterations | Number of Newton iterations taken. |
| residual_norm | Final scaled-residual 2-norm – the quantity the solve drives below its tol. |
| x | Raw converged state vector. |
Methods
| Name | Description |
|---|---|
| composite | Read the hidden interior of a solved composite element. |
| cuton_report | Per-duct higher-order-mode cut-on frequencies and the plane-wave ceiling. |
| edge | Return a {field: value} dict of all derived quantities on edge e. |
| eigenmodes | Free-oscillation eigenmodes of the perturbation network on this mean flow. |
| field | Return the named field across all edges. |
| forced_response | Perturbation field under each terminal’s declared boundary condition, on this mean flow. |
| from_yaml | Restore a solution embedded in a saved UI/YAML case, skipping a cold re-solve. |
| marker | Transported burnt marker on edge e (0 fresh / unburnt, 1 burnt). |
| mixture_fractions | Transported feed-stream mixture fractions {stream_label: xi} on edge e. |
| nyquist_stability | Unstable-mode count from the real-frequency Nyquist sweep, on this mean flow. |
| perturbation_response | Transfer / scattering response by driving each terminal wave, on this mean flow. |
| plot | Draw this solved network as a node/edge diagram with the solved state on the edges (Plotly). |
| print_residuals | Print the residual broken down equation-by-equation. |
| print_states | Print the per-edge mean-flow state table to the screen. |
| residuals | Return the converged residual broken down equation-by-equation. |
| save | Alias for :meth:to_yaml (kept for intuitive usage). |
| species | Solved chemical species {name: fraction} on edge e. |
| table | Return the per-edge state table (rows are fields, columns are edges). |
| to_yaml | Write the network and this solution’s results to a UI-readable YAML case. |
| unchoked_nozzles | Choked-nozzle outlets whose set back pressure is too high for the throat to choke. |
| verify | Run the post-solve model-validity checks and return one message per issue found. |
composite
shell.Solution.composite(key)Read the hidden interior of a solved composite element.
A composite (e.g. an orifice or a tapered nozzle) is added as one element but expands into several sub-elements joined by internal edges that :meth:table hides by default. This returns a :class:~nefes.elements.composite.CompositeView over that interior – its internal edges, and, for a contracting composite, its throat.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | str or int | The composite’s name or its user node id. | required |
Returns
| Name | Type | Description |
|---|---|---|
| CompositeView | A view exposing the composite’s internal edges and (where it contracts) throat state. |
cuton_report
shell.Solution.cuton_report(section='circular', aspect=1.0)Per-duct higher-order-mode cut-on frequencies and the plane-wave ceiling.
The Nefes acoustic layer is plane-wave (1-D); it is valid only below the first duct cut-on frequency. This reports the cut-on of every edge (from its area, sound speed and Mach) and the network-wide ceiling (:attr:~nefes.perturbation.CutOnReport.f_cuton) – keep any perturbation analysis below it.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| section | (circular, square, rectangular) | Assumed duct cross-section shape (Nefes ducts store only an area). | "circular" |
| aspect | float | Width-to-height ratio (>= 1) for section="rectangular", used to recover the larger transverse dimension (which sets the cut-on) from the area. Ignored for the circular and square sections; default 1.0 (a square). |
1.0 |
Returns
| Name | Type | Description |
|---|---|---|
| nefes.perturbation.CutOnReport |
edge
shell.Solution.edge(e)Return a {field: value} dict of all derived quantities on edge e.
eigenmodes
shell.Solution.eigenmodes(freq_band=None, **kwargs)Free-oscillation eigenmodes of the perturbation network on this mean flow.
A bound form of :func:nefes.perturbation.eigenmodes that supplies this solution’s compiled problem and mean state; see it for the full parameter set and the growth-rate sign convention. Set the terminal :class:~nefes.perturbation.PerturbationBC s on the network before solving.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| freq_band | tuple of float | (f_lo, f_hi) real-frequency search window, in Hz. |
None |
| **kwargs | Forwarded to :func:nefes.perturbation.eigenmodes (e.g. growth_band, isentropic). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| EigenmodeResult |
See Also
nefes.perturbation.eigenmodes : the underlying routine.
field
shell.Solution.field(name)Return the named field across all edges.
Names are the keys of the per-edge state: mdot, p, h_t, rho, u, T, c, M, p_t, area, plus the mixture molar mass W [kg/mol] and specific heat cp [J/(kg K)] (the latter consistent with the local sound speed – exact for a perfect gas, the frozen value on an unburnt edge and the equilibrium value on a burnt one).
forced_response
shell.Solution.forced_response(freqs, **kwargs)Perturbation field under each terminal’s declared boundary condition, on this mean flow.
A bound form of :func:nefes.perturbation.forced_response: the forcing is whatever the terminals’ driven :class:~nefes.perturbation.PerturbationBC s inject.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| freqs | array_like | Frequencies (Hz) to solve at. | required |
| **kwargs | Forwarded to :func:nefes.perturbation.forced_response (e.g. isentropic). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| ForcedResponse |
See Also
nefes.perturbation.forced_response : the underlying routine.
from_yaml
shell.Solution.from_yaml(path, method='warm', dataset='Mean flow', **solve_kw)Restore a solution embedded in a saved UI/YAML case, skipping a cold re-solve.
The inverse of :meth:to_yaml. Reads the network and rebuilds the solver state from the saved datasets; method toggles how the stored state is trusted – "warm" (default) verifies it with a single kappa = 0 solve (returns at iteration 0 with no Jacobian when the state is faithful), "deserialize" returns it verbatim with no solve. Thin wrapper over :func:nefes.io.load_solution; see it for the full parameter set.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| path | str | Path to a .yaml case carrying an embedded solution. |
required |
| method | (warm, deserialize) | Restore strategy (default "warm"). |
"warm" |
| dataset | str | Name of the mean-flow dataset to restore (default "Mean flow"). |
'Mean flow' |
| **solve_kw | Forwarded to :meth:Network.solve when method="warm". |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| Solution |
marker
shell.Solution.marker(e)Transported burnt marker on edge e (0 fresh / unburnt, 1 burnt).
The scalar that gates the reacting closure’s frozen/equilibrium blend. Bimodal at convergence (a flame is a discrete 0 -> 1 jump), so it reads ~0 on an unburnt edge and ~1 on a burnt one. Returns 0.0 when the network carries no marker (a perfect gas, or a reacting network built with an explicit hard per-edge closure).
mixture_fractions
shell.Solution.mixture_fractions(e)Transported feed-stream mixture fractions {stream_label: xi} on edge e.
These are the conserved scalars the solver carries (one per distinct injected feed), not chemical species; for the actual species use :meth:species. Empty for a perfect gas with no passive scalars.
nyquist_stability
shell.Solution.nyquist_stability(freqs, **kwargs)Unstable-mode count from the real-frequency Nyquist sweep, on this mean flow.
A bound form of :func:nefes.perturbation.nyquist_stability; the network must carry at least one dynamic source (a flame FTF or a fluctuating injector).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| freqs | array_like | Real frequencies (Hz), spanning ~0 to past the highest mode. |
required |
| **kwargs | Forwarded to :func:nefes.perturbation.nyquist_stability (e.g. isentropic). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| NyquistResponse |
See Also
nefes.perturbation.nyquist_stability : the underlying routine.
perturbation_response
shell.Solution.perturbation_response(freqs, forcing=None, **kwargs)Transfer / scattering response by driving each terminal wave, on this mean flow.
A bound form of :func:nefes.perturbation.perturbation_response; the matrices it yields are independent of the physical terminations.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| freqs | array_like | Frequencies (Hz) to solve at. | required |
| forcing | tuple of int | The pair of terminal node ids to force (default: every open terminal). | None |
| **kwargs | Forwarded to :func:nefes.perturbation.perturbation_response (e.g. excite). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| PerturbationResponse |
See Also
nefes.perturbation.perturbation_response : the underlying routine.
plot
shell.Solution.plot(color_by=None, width_by=None, **kwargs)Draw this solved network as a node/edge diagram with the solved state on the edges (Plotly).
The same diagram as :meth:Network.plot, with this solution attached: the edge hover carries the headline state, and color_by / width_by map any solved edge field onto edge color / arrow width. Shares one backend (:func:nefes.plotting.plot_network_topology) with the structural view, so topology and results read the same way.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| color_by | str | Solved edge field to color the edges by, e.g. "T", "M", "mdot" (keys of the per-edge state; see :meth:field). Adds a colorbar and labels each edge with its value. |
None |
| width_by | str | Solved edge field whose magnitude scales each edge’s arrow width (e.g. "mdot" for a flow-weighted diagram, "area" for a geometry-weighted one). |
None |
| **kwargs | Forwarded to :func:nefes.plotting.plot_network_topology (e.g. colorscale, show_edge_labels, show_areas, title, height, width). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| plotly.graph_objects.Figure |
print_residuals
shell.Solution.print_residuals(sort=True, top=None, precision=4, file=None)Print the residual broken down equation-by-equation.
Thin wrapper over :func:nefes.solver.report.print_residuals; see it for the column layout.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sort | bool | Order rows by descending \|scaled residual\| (default True). |
True |
| top | int | Show only the worst top equations (default: all). |
None |
| precision | int | Significant digits printed per residual value (default 4). | 4 |
| file | file - like | Destination stream forwarded to :func:print (default sys.stdout). |
None |
print_states
shell.Solution.print_states(edges=None, precision=5, file=None)Print the per-edge mean-flow state table to the screen.
Thin wrapper over :func:nefes.solver.report.print_states; see it for the column layout. In a notebook (and when file is not given) the table renders as rich HTML; otherwise a fixed-width text table is printed.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| edges | sequence of int | Edge indices to include, in the given order (default: every edge). | None |
| precision | int | Number of significant digits printed per value (default 5). | 5 |
| file | file - like | Destination stream forwarded to :func:print (default sys.stdout). |
None |
residuals
shell.Solution.residuals()Return the converged residual broken down equation-by-equation.
Resolves the single :attr:residual_norm into its per-equation contributions, keyed by a human-readable label (element/equation for node rows, edge + scalar for transport rows). Useful for spotting which equation a non-converged solve left large.
Returns
| Name | Type | Description |
|---|---|---|
| dict | {label: scaled_residual} for every equation, in residual-row order. |
save
shell.Solution.save(path, dataset='Mean flow', **kwargs)Alias for :meth:to_yaml (kept for intuitive usage).
species
shell.Solution.species(e, basis='mole')Solved chemical species {name: fraction} on edge e.
A burnt (equilibrium) edge reports its HP-equilibrium products; an unburnt (frozen) edge reports the forward blend of its feed streams; a perfect-gas edge has no chemical species (use :meth:mixture_fractions for its passive scalars).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| e | int | Edge id. | required |
| basis | (mole, mass) | Mole or mass fractions (default "mole"). |
"mole" |
Returns
| Name | Type | Description |
|---|---|---|
| dict | {species_name: fraction} for the species present on the edge. |
table
shell.Solution.table(show_internal=True)Return the per-edge state table (rows are fields, columns are edges).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| show_internal | bool | When False and the network carries composite elements, drop the composite internal edge columns, leaving only the user-facing edges (which keep their ids; internals append at the tail). Default True (every edge). |
True |
to_yaml
shell.Solution.to_yaml(path, dataset='Mean flow', **kwargs)Write the network and this solution’s results to a UI-readable YAML case.
Embeds the mean-flow fields (and any transported chemistry) as a named dataset the UI can load. If path does not yet exist, a fresh case is written. If it exists – and already holds this same network – the results are appended as a new dataset, so several solutions (e.g. operating points) can be overlaid in one file from repeated calls with distinct dataset names.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| path | str | Destination .yaml path. Appended to when it already exists. |
required |
| dataset | str | Name for this solution’s mean-flow dataset (default "Mean flow"). Appending a dataset whose name is already present in the file raises ValueError. |
'Mean flow' |
| **kwargs | Forwarded to :func:nefes.io.save_case / :func:nefes.io.dump_case (e.g. fields, node_data, forced, title). |
{} |
unchoked_nozzles
shell.Solution.unchoked_nozzles()Choked-nozzle outlets whose set back pressure is too high for the throat to choke.
A :func:~nefes.elements.catalog.choked_nozzle_outlet asserts a sonic throat, which holds only while the ambient back pressure sits below the throat’s critical (sonic) pressure p* = p_t (2 / (g + 1))^(g / (g - 1)) (g the local ratio of specific heats, g = c^2 W / (R_u T)). For every such element given a back_pressure at construction, this compares it to p* at the converged state and returns the nozzles that would not actually choke – the compact choked-nozzle model does not apply to them. One of the checks :meth:verify runs after a solve; call it directly to inspect.
Returns
| Name | Type | Description |
|---|---|---|
| list of dict | One entry per offending nozzle: {"node", "name", "edge", "back_pressure", "critical_pressure", "p_t"}. Empty when every nozzle with a set back pressure is genuinely choked (or none set one). |
verify
shell.Solution.verify()Run the post-solve model-validity checks and return one message per issue found.
The single home for checks that can only be evaluated once the mean flow is converged (as opposed to the structural checks :func:nefes.shell.build.validate_network runs at compile time). Each check is gated by its CHECK_* toggle in :mod:nefes.shell.checks; currently this is the choked-nozzle back-pressure check (:meth:unchoked_nozzles, gated by CHECK_CHOKED_NOZZLE). :meth:Network.solve calls this on a converged solution and re-emits each message as a warning; call it directly to collect them without the warnings machinery.
Returns
| Name | Type | Description |
|---|---|---|
| list of str | Human-readable messages, one per issue; empty when the solution passes every check. |