Averaging

Functions for integration and averaging over 2D blocks.

This module implements averaging methods for reducing spatially-varying 2D flow fields to representative scalar quantities, essential for comparing CFD results with mean-line design points and experimental measurements. The module provides area averaging, mass-flux averaging, and mixed-out averaging methods following turbomachinery conventions. As discussed by Cumpsty and Horlock [1], dimensional reduction from 2D to 0D inherently loses information, requiring careful selection of which flow properties to conserve. Burdett and Povey [2] demonstrate that mixed-out averages minimize sensitivity to streamwise location variations. All averaging functions operate on 2D Block objects and support both absolute and relative reference frames for turbomachinery with rotating components, enabling consistent performance metric extraction across blade rows.

ember.average.flow_mass(block, axes=None)[source]

Integrate mass flow through faces of a 2D block.

Calculates the mass flow over the block faces,

\[\dot{m} = \int \rho \mathbf{V}\cdot\mathrm{d}\mathbf{A} \,.\]
Parameters:
  • block (Block, shape (ni, nj) or (ntri, 3)) – 2D structured or triangulated block.

  • axes (tuple of int, default (0, 1)) – For structured grids, axes over which to sum the mass flow; for triangulated grids, should be None to sum over all faces.

Returns:

mass_flow – Mass flow rate through the block.

Return type:

float

ember.average.flow_conserved(block, axes=None)[source]

Integrate conserved flows through faces of a 2D block.

Calculates the conserved flows over the block faces,

\[\int \mathcal{F}\cdot\mathrm{d}\mathbf{A} \,,\]

where the conserved flux tensor \(\mathcal{F}\) carries the fluxes of mass, axial momentum, radial momentum, angular momentum and stagnation enthalpy (energy),

\[\begin{split}\mathcal{F} = \rho \mathbf{V} \begin{bmatrix} 1 \\ V_x \\ V_r \\ r V_\theta \\ h_0 \end{bmatrix} + p \begin{bmatrix} \mathbf{0} \\ \mathbf{e}_x \\ \mathbf{e}_r \\ r\,\mathbf{e}_\theta \\ \Omega r\,\mathbf{e}_\theta \end{bmatrix} \,.\end{split}\]
Parameters:
  • block (Block, shape (ni, nj) or (ntri, 3)) – 2D structured or triangulated block.

  • axes (tuple of int, default (0, 1)) – For structured grids, axes over which to sum the flows; for triangulated grids, should be None to sum over all faces.

Returns:

flow_conserved – Integrated conserved flows

Return type:

Array shape (5,)

ember.average.mass_average(scalar_node, block, axes=None)[source]

Take mass-weighted average of a 2D nodal scalar field.

Calculates the mass-weighted average of the scalar field \(\phi\),

\[\bar{\phi} = \frac{\int \phi\, \rho \mathbf{V}\cdot\mathrm{d}\mathbf{A}} {\int \rho \mathbf{V}\cdot\mathrm{d}\mathbf{A}} \,.\]
Parameters:
  • scalar_node (Array, shape (ni, nj) or (ntri, 3)) – Scalar field values at grid nodes

  • block (Block, shape (ni, nj) or (ntri, 3)) – 2D structured or triangulated block

  • axes (tuple of int, default (0, 1)) – For structured grids, axes over which to average; for triangulated grids, should be None to average over all faces

Returns:

avg_scalar – Mass-weighted average value

Return type:

float

Raises:

ValueError – If the net mass flux through the block is zero

ember.average.area_average(scalar_node, block, axes=None)[source]

Take area-weighted average of a 2D nodal scalar field.

Calculates the area-weighted average of the scalar field \(\phi\),

\[\bar{\phi} = \frac{\int \phi\, \mathrm{d}A}{\int \mathrm{d}A} \,.\]
Parameters:
  • scalar_node (Array, shape (ni, nj) or (ntri, 3)) – Scalar field values at grid nodes

  • block (Block, shape (ni, nj) or (ntri, 3)) – 2D structured or triangulated block

  • axes (tuple of int, default (0, 1)) – For structured grids, axes over which to average; for triangulated grids, should be None to average over all faces

Returns:

avg_scalar – Area-weighted average value

Return type:

float

ember.average.total_area(block)[source]

Compute total vector area of a 2D block.

Calculates the total vector area as the integral of the face area vectors,

\[\mathbf{A} = \int \mathrm{d}\mathbf{A} \,.\]
Parameters:

block (Block, shape (ni, nj) or (ntri, 3)) – 2D structured or triangulated block

Returns:

A – Total area of the cut [m^2] in polar coordinates (Ax, Ar, At)

Return type:

Array, shape (3,)

ember.average.mix_out(block, AR=1.0)[source]

Mix out a 2D cut to uniformity, optionally through a contracted area.

The mixed-out state is the uniform flow that, passed through the total area \(\mathbf{A} = \int \mathrm{d}\mathbf{A}\), carries the same conserved flows as the non-uniform cut. Its conserved variables \(\mathcal{U}\) are found by solving

\[\mathcal{F}(\mathcal{U})\cdot\mathbf{A} = \int \mathcal{F}\cdot\mathrm{d}\mathbf{A} \,,\]

for the five conserved flows (mass, axial and radial momentum, angular momentum and energy), where \(\mathcal{F}\) is the flux tensor of flow_conserved(). The five equations are solved iteratively by Newton steps on \(\mathcal{U}\). Mixing to uniformity generates entropy, so the result has higher entropy than the original state.

The optional area ratio AR then contracts (AR<1) or expands the uniform state isentropically from \(\mathbf{A}\) to AR times \(\mathbf{A}\), conserving mass, stagnation enthalpy, entropy and angular momentum \(r V_\theta\) (at fixed radius) while holding the pitch angle \(\beta\). This second step is reversible, so the mixing loss is independent of AR and AR=1 recovers the plain mix-out. The contraction stays on the mixed-out sub/supersonic branch and raises RuntimeError if it would choke.

Parameters:
  • block (Block, shape (ni, nj) or (ntri, 3)) – 2D block, can be structured or triangulated.

  • AR (float, default 1.0) – Area ratio for the isentropic contraction applied after mixing out. AR=1 retains the constant-area mix-out; AR<1 contracts the uniform state to area AR * A.

Returns:

mix – New scalar block with mixed-out uniform state.

Return type:

Block, shape ()