shell.Network
shell.Network(
gas=None,
nodes=None,
edges=None,
*,
edge_models=None,
require_connected=None,
**refs,
)The main object for building and solving flow networks.
A network can be built incrementally with :meth:add / :meth:connect, specified complete in one shot via the nodes / edges constructor arguments, or loaded from a saved case with :meth:from_yaml / :meth:from_dict. Call :meth:solve for the steady mean flow (a :class:Solution) or :meth:compile / :attr:problem for the immutable compiled problem. Parameter-swept stability follows from :meth:eigenvalue_trajectory / :meth:nyquist_stability_map. Write it back out with :meth:to_yaml.
Attributes
| Name | Description |
|---|---|
| problem | The compiled problem for the current topology, built on first access and cached. |
Methods
| Name | Description |
|---|---|
| add | Add an element and return its node index. |
| builder | A one-parameter build(p) closure over :meth:with_params. |
| compile | Compile the elements and edges into an immutable CompiledProblem and cache it. |
| connect | Add a directed edge from element tail to element head, returning its edge id. |
| copy | A deep copy of this network’s specification (elements, edges, references). |
| edge_between | Return the id of the edge connecting elements a and b, in either orientation. |
| edges_of | Ids of the edges incident to an element, resolved by name or node index. |
| eigenvalue_trajectory | Track the eigenmode spectrum as one parameter is swept. |
| element | The element spec behind a node index or display name. |
| element_index | Resolve an element reference (node index or unique display name) to its node index. |
| element_name | Display label of an element, the inverse of :meth:element_index. |
| from_dict | Build a network from an in-memory case dictionary. |
| from_yaml | Build a network from a saved UI/YAML case file. |
| get | Read one parameter by its dotted address. |
| initial_guess | Return the solver’s initial state guess for the compiled problem. |
| nodes_of | The (tail, head) element indices an edge connects. |
| nyquist_stability_map | Unstable-mode count across a parameter sweep, on the real-frequency axis. |
| parameters | The inventory of every addressable parameter: address, value, unit, bounds. |
| plot | Draw the network as a node/edge diagram (Plotly). |
| save | Alias for :meth:to_yaml (kept for intuitive usage). |
| set | Set named parameters on one element, in place, with fail-closed validation. |
| set_dynamic_source | Attach (or replace) the dynamic-source descriptor on an already-added element. |
| set_perturbation_bc | Attach (or replace) the acoustic termination on an already-added boundary element. |
| solve | Compile and solve the steady mean flow, returning a Solution. |
| to_yaml | Write this network as a UI-readable YAML case (no result data). |
| update | Apply a batch of dotted-address parameter writes, in place. |
| with_params | A modified deep copy: this network with the given parameter writes applied. |
add
shell.Network.add(spec)Add an element and return its node index.
Element names must be unique. A factory default (the caller did not pass name) is always numbered – a lone duct becomes duct-1 – while a name the caller chose is kept and only suffixed on an actual clash; the name_auto flag on the spec records which.
builder
shell.Network.builder(address, **fixed)A one-parameter build(p) closure over :meth:with_params.
The build contract the continuation drivers take (:func:~nefes.perturbation.stability.trajectory.eigenvalue_trajectory, :func:~nefes.perturbation.response.nyquist.nyquist): build(p) returns a fresh network with address set to p, leaving this base pristine.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| address | str | The swept parameter’s dotted address (e.g. "flame.Qdot"). |
required |
| **fixed | Additional {address: value} writes applied at every point (keyword form; dotted addresses with characters invalid in a keyword can be passed by building the closure manually with :meth:with_params). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| callable | build(p) -> Network. |
Examples
>>> traj = eigenvalue_trajectory(net.builder("flame.Qdot"), np.linspace(1e3, 5e3, 21),
... freq_band=(50.0, 400.0), param_name="Qdot")compile
shell.Network.compile()Compile the elements and edges into an immutable CompiledProblem and cache it.
Rebuilds unconditionally (refreshing the :attr:problem cache); prefer :attr:problem when a cached compile is enough.
connect
shell.Network.connect(
tail,
head,
area,
name='',
*,
tail_port=None,
head_port=None,
edge_model=None,
)Add a directed edge from element tail to element head, returning its edge id.
The returned integer is the edge index in the compiled problem – capture it to wire a dynamic source’s ref_edge (e.g. the edge just upstream of a flame) without guessing.
tail_port/head_port pin the local port indices at each endpoint; leave them None to let the compiler auto-assign ports in attachment order.
edge_model is an advanced, keyword-only override of the per-edge thermo-model id (a hard frozen/equilibrium closure); leave it None to use the gas config’s default model – a reacting network gates the frozen/equilibrium split automatically off the transported burnt marker.
copy
shell.Network.copy()A deep copy of this network’s specification (elements, edges, references).
Edge order, port pins and names are preserved by construction, so the copy compiles to the same problem layout and a warm start from this network’s solution stays valid. The gas model is shared (an immutable configuration); the compiled-problem cache is not copied.
Returns
| Name | Type | Description |
|---|---|---|
| Network |
edge_between
shell.Network.edge_between(a, b)Return the id of the edge connecting elements a and b, in either orientation.
A convenience for recovering an edge index after assembly (e.g. to set a dynamic source’s ref_edge) when the value returned by :meth:connect was not captured. The lookup ignores wiring orientation: edge_between("cold", "flame") and edge_between("flame", "cold") return the same edge id, since an edge id names the edge regardless of which end you list first. Read the stored orientation with :meth:nodes_of.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| a | int or str | The two endpoints, each given as a node index (as returned by :meth:add) or the element’s display name. Names are resolved through :meth:element_index, and the two forms may be mixed. |
required |
| b | int or str | The two endpoints, each given as a node index (as returned by :meth:add) or the element’s display name. Names are resolved through :meth:element_index, and the two forms may be mixed. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| int |
Raises
| Name | Type | Description |
|---|---|---|
| KeyError | Unknown element name or node index out of range (via :meth:element_index). |
|
| ValueError | No edge joins the pair, or more than one does (parallel or antiparallel edges). |
See also
edges_of : every edge incident to one element, when only one endpoint is known. nodes_of : the (tail, head) orientation of a known edge. element_index : the name-to-index resolution applied to each endpoint.
edges_of
shell.Network.edges_of(element, direction='both')Ids of the edges incident to an element, resolved by name or node index.
The companion to :meth:edge_between for when only one endpoint is known: it returns every edge touching element rather than the single edge between an ordered pair. The ids index the same edge table as :meth:connect’s return and :meth:edge_between, so they read straight off a solution (sol.edge(e), sol.field(name)[e]).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| element | int or str | Node index (as returned by :meth:add) or the element’s display name. |
required |
| direction | (both, 'in', out) | Which incident edges to return: "out" for edges leaving the element (it is the edge’s tail), "in" for edges entering it (it is the edge’s head), or "both" (default) for either. This is the wiring orientation, not the solved flow direction (which may run either way along an edge). |
"both" |
Returns
| Name | Type | Description |
|---|---|---|
| list of int | The incident edge ids, in ascending order (empty if the element has no edges). |
Raises
| Name | Type | Description |
|---|---|---|
| KeyError | Unknown element name or node index out of range (via :meth:element_index). |
|
| ValueError | direction is not one of "both", "in", "out". |
See also
edge_between : the single edge between a known ordered pair of elements. nodes_of : the (tail, head) elements a known edge connects.
Examples
>>> net.edges_of("plenum", direction="out")
[2, 5, 8, 11]eigenvalue_trajectory
shell.Network.eigenvalue_trajectory(address, params, **kwargs)Track the eigenmode spectrum as one parameter is swept.
A bound form of :func:nefes.perturbation.eigenvalue_trajectory: it builds each swept network with :meth:builder (this base stays pristine), seeds the spectrum once, then continues each mode along params.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| address | str | The swept parameter’s dotted address (e.g. "flame.Qdot"). |
required |
| params | array_like | The parameter values, in continuation order. | required |
| **kwargs | Forwarded to :func:nefes.perturbation.eigenvalue_trajectory (e.g. freq_band, growth_band, isentropic); param_name defaults to address. |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| TrajectoryResult |
See Also
nefes.perturbation.eigenvalue_trajectory : the underlying routine. builder : the build(p) closure this passes through.
element
shell.Network.element(key)The element spec behind a node index or display name.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | int or str | Node index or the element’s display name. | required |
Returns
| Name | Type | Description |
|---|---|---|
| ElementSpec or CompositeElementSpec |
Examples
>>> net.element("inlet").fparams
[0.3, 700.0]See Also
get : read a single named parameter instead of the raw spec.
element_index
shell.Network.element_index(key)Resolve an element reference (node index or unique display name) to its node index.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | int or str | Node index (as returned by :meth:add), or the element’s display name. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| int |
Raises
| Name | Type | Description |
|---|---|---|
| KeyError | Unknown name (with near-match suggestions) or index out of range. |
element_name
shell.Network.element_name(key)Display label of an element, the inverse of :meth:element_index.
Turns a node index (as returned by :meth:add, :meth:nodes_of, or an edges_of result) back into the element’s name, the stable handle used across the API and in parameter addresses. Passing a name returns it unchanged, so the two are interchangeable wherever a label is wanted. Falls back to #<index> for the rare unnamed element.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | int or str | Node index or the element’s display name. | required |
Returns
| Name | Type | Description |
|---|---|---|
| str |
Raises
| Name | Type | Description |
|---|---|---|
| KeyError | Unknown name (with near-match suggestions) or index out of range (via :meth:element_index). |
Examples
>>> t, h = net.nodes_of(net.edge_between("cold", "flame"))
>>> net.element_name(t), net.element_name(h)
('cold', 'flame')See Also
element_index : the inverse, resolving a label to its node index. element : the full element spec behind a label or index.
from_dict
shell.Network.from_dict(data)Build a network from an in-memory case dictionary.
The dictionary is the parsed form of the same schema :meth:from_yaml reads, so this is the file-less equivalent of :meth:from_yaml.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | dict | A case document (a model section with nodes / edges, as in a YAML case). |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Network |
from_yaml
shell.Network.from_yaml(path)Build a network from a saved UI/YAML case file.
A convenience so callers need not reach into :mod:nefes.io; equivalent to :func:nefes.io.load_case.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| path | str | Path to a .yaml case file (as written by :meth:to_yaml). |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Network |
get
shell.Network.get(address)Read one parameter by its dotted address.
Addresses are "element.param" / "edge.area" strings (elements and edges by display name) plus the bare network references ("p_ref", "T_ref"). An unknown address raises with near-match suggestions. "element.area" reads the shared incident-edge area of a single-port or constant-area element.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| address | str | The dotted address, e.g. "inlet.mdot", "orifice.throat_area", "e3.area". |
required |
Returns
| Name | Type | Description |
|---|---|---|
| object | The current value (a float for numeric parameters). |
Examples
>>> net.get("inlet.mdot")
0.3
>>> net.get("e0.area")
0.01See Also
parameters : the full inventory of addressable parameters.
initial_guess
shell.Network.initial_guess(**kw)Return the solver’s initial state guess for the compiled problem.
nodes_of
shell.Network.nodes_of(edge)The (tail, head) element indices an edge connects.
The inverse of :meth:edges_of: given an edge id (from :meth:connect, :meth:edge_between, or :meth:edges_of) it returns the two elements the edge joins, tail first (the source endpoint in the wiring orientation), head second. Resolve either index to its name or spec with :meth:element.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| edge | int | Edge id, in range(len(edges)). |
required |
Returns
| Name | Type | Description |
|---|---|---|
| tuple of int | The (tail, head) node indices. |
Raises
| Name | Type | Description |
|---|---|---|
| IndexError | edge is not a valid edge id for this network. |
See also
edges_of : the edges incident to a known element.
Examples
>>> t, h = net.nodes_of(0)
>>> net.element(t).name, net.element(h).name
('inlet', 'duct')nyquist_stability_map
shell.Network.nyquist_stability_map(address, params, freqs, **kwargs)Unstable-mode count across a parameter sweep, on the real-frequency axis.
A bound form of :func:nefes.perturbation.nyquist_stability_map: it builds each swept network with :meth:builder (this base stays pristine). The network must carry at least one dynamic source.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| address | str | The swept parameter’s dotted address (e.g. "flame.n"). |
required |
| params | array_like | The parameter values to sweep. | required |
| freqs | array_like | Real frequencies (Hz) for the Nyquist locus at each point. | required |
| **kwargs | Forwarded to :func:nefes.perturbation.nyquist_stability_map; param_name defaults to address. |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| NyquistStabilityMap |
See Also
nefes.perturbation.nyquist_stability_map : the underlying routine. builder : the build(p) closure this passes through.
parameters
shell.Network.parameters(advanced=False)The inventory of every addressable parameter: address, value, unit, bounds.
The read-only companion of :meth:get / :meth:set: one row per named element parameter (in node order), per edge area, and per network-level reference. The returned :class:~nefes.shell.params.ParameterInventory is a list of :class:~nefes.shell.params.ParameterInfo rows with dict-style access by address and table reprs.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| advanced | bool | Include the advanced knobs (smoothing eps, ref_port, the solver seed references) usually left alone (default False). |
False |
Returns
| Name | Type | Description |
|---|---|---|
| ParameterInventory |
Examples
>>> net.parameters()["inlet.mdot"].value
0.3See Also
get, set, update, with_params
plot
shell.Network.plot(**kwargs)Draw the network as a node/edge diagram (Plotly).
A structural view by default: element indices/names and edge directions, with each edge’s arrow width scaled by its area (width_by="area"), so the geometry reads at a glance. Pass width_by=None for uniform arrows, or another field (with a converged solution=) to weight by it instead; color_by similarly tints the edges, and :meth:Solution.plot is the same diagram driven from a solution. Thin wrapper over :func:nefes.plotting.plot_network_topology; see it for the full keyword set.
Returns
| Name | Type | Description |
|---|---|---|
| plotly.graph_objects.Figure |
save
shell.Network.save(path, **kwargs)Alias for :meth:to_yaml (kept for intuitive usage).
set
shell.Network.set(element, **params)Set named parameters on one element, in place, with fail-closed validation.
Every value is validated against the element’s declared schema (units, bounds, types) before anything is written – an out-of-range value raises a named error, exactly as the element’s factory would. A composite element is rebuilt through its factory (its internals re-derived consistently), never patched. area= on a single-port or constant-area element fans out to all its incident edges. The compiled-problem cache is invalidated; topology is never touched, so a previous solution remains a valid warm start (solve(x0=prev.x)).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| element | int or str | Element node index or display name. | required |
| **params | name=value pairs from the element’s parameter set (see :meth:parameters). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| int | The element’s node index, for chaining. |
Examples
>>> net.set("inlet", mdot=0.5, Tt=720.0)
0
>>> net.set("orifice", throat_area=1.2e-3)
3See Also
update : batch writes by dotted address. with_params : the functional (copying) variant recommended for parameter studies.
set_dynamic_source
shell.Network.set_dynamic_source(node, source)Attach (or replace) the dynamic-source descriptor on an already-added element.
A named convenience over the generic :meth:set (set(node, dynamic_source=...)), so the write is validated against the element’s parameter schema.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| node | int or str | Element index (as returned by :meth:add) or display name. |
required |
| source | DynamicSource or None | The descriptor (e.g. from :func:nefes.elements.dynamic_source.n_tau_flame); None clears it. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| int | The element’s node index, for chaining. |
set_perturbation_bc
shell.Network.set_perturbation_bc(node, bc)Attach (or replace) the acoustic termination on an already-added boundary element.
A named convenience over the generic :meth:set (set(node, perturbation_bc=...)), so the write is validated against the element’s parameter schema. Only the single-port boundary terminations (inlets, outlets, wall) carry a perturbation BC.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| node | int or str | Element index (as returned by :meth:add) or display name. |
required |
| bc | PerturbationBC or None | The termination (e.g. PerturbationBC.open_end()); None restores the inherited linearized boundary row. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| int | The element’s node index, for chaining. |
solve
shell.Network.solve(x0=None, **kw)Compile and solve the steady mean flow, returning a Solution.
Keyword arguments
x0 : ndarray, optional Initial state, shape (3, E) (default: a uniform co-directional guess). tol : float, optional Convergence tolerance on the scaled residual 2-norm (default 1e-10). max_iter : int, optional Maximum Newton iterations per continuation stage (default 80). kappa_stages : sequence of float, optional Artificial-resistance continuation schedule, warm-started in order (default (0.1, 0.01, 0.0)). verbose : int or bool, optional Progress verbosity (default 0). 0/False is silent; 1/True prints a one-line gross-residual summary per continuation stage; 2 additionally prints the scaled residual broken down by equation kind (mass, pressure, energy, then each composition scalar) every progress_interval iterations. progress_interval : int, optional Iteration stride for the per-iteration prints at verbose >= 2 (default 1).
Returns
| Name | Type | Description |
|---|---|---|
| Solution | The converged mean-flow result with named edge-field access. |
Notes
A solve that does not converge returns its (partial) Solution and emits a warning; reading a field off a state that cannot be recovered raises a clear error naming the non-convergence rather than an opaque linear-algebra failure from the closure.
to_yaml
shell.Network.to_yaml(path, **kwargs)Write this network as a UI-readable YAML case (no result data).
The inverse of :meth:from_yaml. Thin wrapper over :func:nefes.io.save_case; see it for the full set of keyword options. To embed solved fields as well, use :meth:Solution.to_yaml.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| path | str | Destination .yaml path. |
required |
| **kwargs | Forwarded to :func:nefes.io.save_case. |
{} |
update
shell.Network.update(mapping)Apply a batch of dotted-address parameter writes, in place.
Every address is resolved before anything is written, so a mistyped address leaves the network untouched; values are then validated per element. Element writes are grouped so a composite is rebuilt once with all its updates merged.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| mapping | dict | {address: value}, e.g. {"orifice.throat_area": 1.2e-3, "e3.area": 0.01}. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Network | self, for chaining (net.update({...}).solve()). |
See Also
set : the single-element form. with_params : the functional (copying) variant recommended for parameter studies.
with_params
shell.Network.with_params(mapping)A modified deep copy: this network with the given parameter writes applied.
The recommended idiom for parameter studies – the loaded base stays pristine, no state accumulates across sweep points, and each point is safe to solve independently. Addressing and validation are those of :meth:update.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| mapping | dict | {address: value} writes applied to the copy. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Network | The modified copy; self is untouched. |
Examples
>>> base = nefes.load_case("combustor.yaml")
>>> prev = None
>>> for mdot in np.linspace(0.3, 0.7, 20):
... sol = base.with_params({"inlet.mdot": mdot}).solve(x0=prev.x if prev else None)
... prev = solSee Also
nefes.parameter_study : the warm-start-chained sweep driver built on this. builder : a one-parameter build(p) closure for the continuation drivers.