bird.postprocess package

bird.postprocess.post_quantities module

bird.postprocess.post_quantities.build_loop_direction_field(cell_centers: ndarray, boxes: list[dict]) → ndarray

Per-cell loop-direction field from labelled axis-aligned boxes.

Each cell inherits the (unit) direction of the box that contains its centre. Cells in no box keep NaN (excluded from the average); a cell in more than one box is ambiguous and raises.

Parameters:
  • cell_centers (np.ndarray) – Cell centres, shape (N, 3)

  • boxes (list[dict]) – List of {"min": [x, y, z], "max": [x, y, z], "direction": [dx, dy, dz]}; direction is normalized internally

Returns:

direction_field – Direction field, shape (N, 3), NaN where uncovered

Return type:

np.ndarray

bird.postprocess.post_quantities.build_loop_direction_field_from_path(cell_centers: ndarray, path_points: ndarray, max_dist: float) → ndarray

Per-cell loop-direction field from a centerline polyline.

Each cell within max_dist of the polyline gets the unit tangent of its nearest segment; cells farther away keep NaN (excluded). The polyline ordering sets the circulation sense.

Parameters:
  • cell_centers (np.ndarray) – Cell centres, shape (N, 3)

  • path_points (np.ndarray) – Ordered centerline vertices, shape (M, 3)

  • max_dist (float) – Cells beyond this distance from the path are left uncovered

Returns:

direction_field – Direction field, shape (N, 3), NaN where uncovered

Return type:

np.ndarray

bird.postprocess.post_quantities.compute_ave_bubble_diam(case_folder: str, time_folder: str, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Calculate averaged bubble diameter over the liquid volume

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} d_{\rm gas} dV\]
where:
  • \(V_{\rm liq, tot}\) is the toal volume of liquid in \(m^3\)

  • \(d_{\rm gas}\) is the bubble diameter in \(m\)

  • \(V_{\rm liq}\) is the volume of liquid where \(d_{\rm gas}\) is measured in \(m^3\)

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • diam (float) – Volume averaged gas holdup

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_ave_conc_liq(case_folder: str, time_folder: str, species_name: str = 'CO2', n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Calculate liquid volume averaged concentration of a species at a given time

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} \rho_{\rm liq} Y / W dV_{\rm liq}\]
where:
  • \(V_{\rm liq, tot}\) is the toal volume of liquid

  • \(\rho_{\rm liq}\) is the liquid density

  • \(Y\) is the species mass fraction

  • \(W\) is the species molar mass

  • \(V_{\rm liq}\) is the volume of liquid where \(Y\) is measured

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • species_name (str) – Name of the species

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • conc_ave (float) – Liquid volume averaged species concentration

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_ave_liquid_density(case_folder: str, time_folder: str, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Volume-averaged liquid density over the liquid.

Reads thermo:rho.liquid (then rho.liquid); returns 1000 kg/m3 if neither field is written.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • density (float) – Volume averaged liquid density, in \(kg.m^{-3}\)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_ave_liquid_velocity(case_folder: str, time_folder: str, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Volume-averaged liquid velocity magnitude \(|U_{\rm liq}|\) over the liquid.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • velocity_magnitude (float) – Volume averaged liquid velocity magnitude, in \(m.s^{-1}\)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_ave_y_liq(case_folder: str, time_folder: str, species_name: str = 'CO2', n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Calculate liquid volume averaged mass fraction of a species at a given time

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} Y dV_{\rm liq}\]
where:
  • \(V_{\rm liq, tot}\) is the toal volume of liquid

  • \(Y\) is the species mass fraction

  • \(V_{\rm liq}\) is the volume of liquid where \(Y\) is measured

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • species_name (str) – Name of the species

  • field_dict (dict | None) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • liq_ave_y (float) – Liquid volume averaged mass fraction

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_fitted_kl(case_folder: str, species_names: str | list[str], n_cells: int | None = None, volume_time: str | None = None, num_warmup: int = 4000, num_samples: int = 1000, field_dict: dict | None = None) → tuple[dict, dict, dict]

Fitted mass-transfer coefficient \(kL = kLa / a\).

Same as compute_fitted_kla() but the fitted mean and std of each species are divided by the interfacial area \(a = 6\,\epsilon / d\), evaluated at the last time folder.

Parameters:
  • case_folder (str) – Path to case folder

  • species_names (str | list[str]) – List of species name for which to compute kL

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • num_warmup (int) – Number of MCMC samples in the warmup phase Defaults to 4000

  • num_samples (int) – Number of posterior MCMC samples generated Defaults to 1000

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • kl_spec (dict) – Fitted volume averaged kL for each species, in \(m.h^{-1}\) Keys are species names Values are dictionaries with key ‘mean’ (mean kL value) and ‘std’ (1 standard deviation for the kL value)

  • cstar_spec (dict) – Fitted volume averaged cstar for each species, in \(mol.m^{-3}\) Keys are species names Values are dictionaries with key ‘mean’ (mean cstar value) and ‘std’ (1 standard deviation for the cstar value)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_fitted_kla(case_folder: str, species_names: str | list[str], n_cells: int | None = None, volume_time: str | None = None, num_warmup: int = 4000, num_samples: int = 1000, field_dict: dict | None = None) → tuple[dict, dict, dict]

Calculate \(kLa_{\rm spec}\) and saturation concentration (\(C^*_{\rm spec}\)) for a list of species from time series data (rather than instantaneously).

Given a time series of concentration of species, the following expression is fitted

\[[spec](t) = [spec]^* (1 - \operatorname{exp}(-{kLa}_{\rm spec} t)).\]

where

  • \(kLa_{\rm spec}\) is the mass transfer rate of species \(\rm spec\) in \(h^{-1}\)

  • \(t\) is the time in \(s\)

  • \([spec]^*\) is the estimated saturation concentration of species \(\rm spec\) in \(mol/m^3\)

  • \([spec](t)\) is the instantaneous liquid volume averaged concentration of species \(\rm spec\) in \(mol/m^3\)

Both \([spec]^*\) and \(kLa_{\rm spec}\) are fitted. The fit is done with Markov Chain Monte Carlo which outputs samples of the posterior PDF of \([spec]^*\) and \(kLa_{\rm spec}\).

Parameters:
  • case_folder (str) – Path to case folder

  • species_names (str | list[str]) – List of species name for which to compute kla

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • num_warmup (int) – Number of MCMC samples in the warmup phase Defaults to 4000

  • num_samples (int) – Number of posterior MCMC samples generated Defaults to 1000

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • kla_spec (dict) – Instantaneous volume averaged kLa for each species, in \(h^{-1}\) Keys are species names Values are dictionaries with key ‘mean’ (mean kLa value) and ‘std’ (1 standard deviation for the kLa value)

  • cstar_spec (dict) – Instantaneous volume averaged cstar for each species, in \(mol.m^{-3}\) Keys are species names Values are dictionaries with key ‘mean’ (mean cstar value) and ‘std’ (1 standard deviation for the cstar value)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_froude_number(case_folder: str, time_folder: str, length: float, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Froude number from the liquid-averaged velocity and a given length.

\(Fr = U / \sqrt{g L}\) with \(U\) the liquid-volume-averaged \(|U_{\rm liq}|\) at time_folder, \(g\) from constant/g, and \(L\) the passed length.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • length (float) – Characteristic length \(L\), in \(m\)

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • froude_number (float) – Froude number (dimensionless)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_gas_holdup(case_folder: str, time_folder: str, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Calculate volume averaged gas hold up at a given time

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} (1-\alpha_{\rm liq}) dV\]
where:
  • \(V_{\rm liq, tot}\) is the total volume of liquid in \(m^3\)

  • \(\alpha_{\rm liq}\) is the liquid phase volume fraction

  • \(V\) is the volume of the cells where \(\alpha_{\rm liq}\) is measured in \(m^3\)

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict | None) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • gas_holdup (float) – Volume averaged gas holdup

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_instantaneous_kl(case_folder: str, time_folder: str, species_names: str | list[str], n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[dict, dict]

Calculate the mass-transfer coefficient (\(kL_{\rm spec}\)) and saturation concentration (\(C^*_{\rm spec}\)) for a list of species from instantaneous data (rather than doing a fit over time).

\(kL_{\rm spec}\) is the penetration-theory coefficient that compute_instantaneous_kla() multiplies by the interfacial area \(a = 6 \alpha_{\rm gas} / d_{\rm gas}\) to form \(kLa_{\rm spec}\) (i.e. \(kLa_{\rm spec} = kL_{\rm spec}\, a\)), volume averaged over the liquid.

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} kL_{\rm spec} dV\]
\[kL_{\rm spec} = 3600 \sqrt{\frac{4 D_{\rm spec} |u_{\rm slip}|}{\pi d_{\rm gas}}}\]
where:
  • \(kL_{\rm spec}\) is the mass transfer coefficient in \(m.h^{-1}\)

  • \(d_{\rm gas}\) is the bubble diameter in \(m\). Either read from the time folder, or looked up from phaseProperties

  • \(D_{\rm spec}\) is the species molecular diffusivity in \(m^2.s^{-1}\). Read from globalVars

  • \(|u_{\rm slip}|\) is the magnitude of the slip velocity in \(m.s^{-1}\). Read from the time folder.

  • \(V_{\rm liq}\) is the volume of liquid in \(m^3\). Read from the time folder.

\(C^*_{\rm spec}\) is computed as in compute_instantaneous_kla().

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • species_names (str | list[str]) – List of species name for which to compute kL

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • kl_spec (dict) – Instantaneous volume averaged kL for each species, in \(m.h^{-1}\) Keys are species names Values are the kL values

  • cstar_spec (dict) – Instantaneous volume averaged cstar for each species, in \(mol.m^{-3}\) Keys are species names Values are the cstar values

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_instantaneous_kla(case_folder: str, time_folder: str, species_names: str | list[str], n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[dict, dict, dict]

Calculate \(kLa_{\rm spec}\) and saturation concentration (\(C^*_{\rm spec}\)) for a list of species from instantaneous data (rather than doing a fit over time).

\(kLa_{\rm spec}\) for the species computed from Eq 7 and 8 in “Computational fluid dynamics study of full-scale aerobic bioreactors: Evaluation of gas–liquid mass transfer, oxygen uptake, and dynamic oxygen distribution”, M. J. Rahimi, H. Sitaraman, D. Humbird, J. J. Stickel, Chem. Eng. Research and Design, Vol. 139, pp 293-295, 2018.

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} kLa_{\rm spec} dV\]
\[kLa_{\rm spec} = 3600 \sqrt{\frac{4 D_{\rm spec} |u_{\rm slip}|}{\pi d_{\rm gas}}} \frac{6 \alpha_{\rm gas}}{d_{\rm gas}}\]
\[kLa_{\rm spec} = (\frac{2}{\pi^{1/2}} \times 3600) Re^{1/2} \frac{\mu_{\rm liq}^{1/2}}{D_{\rm spec}^{1/2} \rho_{\rm liq}^{1/2}} \frac{D_{\rm spec}}{d_{\rm gas}} \frac{6}{d_{\rm gas}} \alpha_{\rm gas}\]
\[Re = \frac{\rho_{\rm liq} |u_{\rm slip}| d_{\rm gas}}{\mu_{\rm liq}}\]
where:
  • \(kLa_{\rm spec}\) is the mass transfer rate in \(h^{-1}\)

  • \(d_{\rm gas}\) is the bubble diameter in \(m\). Either read from the time folder, or looked up from phaseProperties

  • \(\alpha_{\rm gas}\) is the volume fraction of gas. Read from the time folder.

  • \(\mu_{\rm liq}\) is the liquid viscosity in \(kg.m^{-1}.s^{-1}\). Either read from the time folder or globalVars.

  • \(\rho_{\rm liq}\) is the liquid density in \(kg.m^{-3}\). Either read from the time folder or assumed to be 1000kg/m3

  • \(D_{\rm spec}\) is the species molecular diffusivity in \(m^2.s^{-1}\). Read from globalVars

  • \(|u_{\rm slip}|\) is the magnitude of the slip velocity in \(m.s^{-1}\). Read from the time folder.

  • \(V_{\rm liq}\) is the volume of liquid in \(m^3\). Read from the time folder.

\[\frac{1}{V_{\rm liq, tot}} \int_{V_{\rm liq}} C^*_{\rm spec} dV\]

\(C^*_{\rm spec}\) computed from Eq 10 in “Computational fluid dynamics study of full-scale aerobic bioreactors: Evaluation of gas–liquid mass transfer, oxygen uptake, and dynamic oxygen distribution”, M. J. Rahimi, H. Sitaraman, D. Humbird, J. J. Stickel, Chem. Eng. Research and Design, Vol. 139, pp 293-295, 2018.

\[C^*_{\rm spec} = \rho_{\rm gas} Y_{\rm spec, gas} He_{\rm spec} / W_{\rm spec}\]
and
  • \(C^{*}_{\rm spec}\) is the saturation concentration of species spec in \(mol.m^{-3}\)

  • \(\rho_{\rm gas}\) is the density of the gas in \(kg.m^{-3}\). Read from the time folder.

  • \(Y_{\rm spec, gas}\) is the mass fraction of species spec in the gas phase. Read from the time folder.

  • \(He_{\rm spec}\) is the Henry’s constant of species spec. Read from globalVars.

  • \(W_{\rm spec}\) is the molar mass of species spec in \(kg.mol^{-1}\). Read from globalVars.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • species_names (str | list[str]) – List of species name for which to compute kla

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • kla_spec (dict) – Instantaneous volume averaged kLa for each species, in \(h^{-1}\) Keys are species names Values are the kLa values

  • cstar_spec (dict) – Instantaneous volume averaged cstar for each species, in \(mol.m^{-3}\) Keys are species names Values are the cstar values

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_loop_velocity(case_folder: str, time_folder: str, loop_direction_field: ndarray, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Loop velocity: liquid velocity projected on the loop direction.

\[\frac{\int_{V_{\rm loop}} \alpha_{\rm liq}\, (\mathbf{U}_{\rm liq} \cdot \hat{\mathbf{e}}_{\rm loop})\, dV}{\int_{V_{\rm loop}} \alpha_{\rm liq}\, dV}\]

Averaged over the liquid on the covered cells. Positive follows the prescribed circulation, negative is reversed.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • loop_direction_field (np.ndarray) – (N, 3) field from a builder, NaN on uncovered cells

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • loop_velocity (float) – Volume averaged loop velocity, in \(m.s^{-1}\)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_sherwood_number(case_folder: str, time_folder: str, length: float, species_name: str, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Sherwood number for one species from the instantaneous kL.

\(Sh = k_L L / D\) with \(k_L\) from compute_instantaneous_kl() at time_folder and the molecular diffusivity \(D\) read as D_<species> from globalVars (the standard Sherwood definition; the turbulent contribution is deliberately excluded).

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • length (float) – Characteristic length \(L\), in \(m\)

  • species_name (str) – Species for which to compute kL and use D_<species>

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • sherwood_number (float) – Sherwood number (dimensionless)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_superficial_gas_velocity(case_folder: str, time_folder: str, n_cells: int | None = None, volume_time: str | None = None, direction: int | None = None, cell_centers_file: str | None = None, height: float | None = None, use_pv: bool = False, field_dict: dict | None = None) → tuple[float, dict]

Calculate superficial gas velocity (in m/s) in a given direction at a given time

Without the paraview operations (use_pv==False)

\[\frac{1}{V_{\rm height, tot}} \int_{V_{\rm height}} U_{\rm gas} \alpha_{\rm gas} dV\]
where:
  • \(V_{\rm height, tot}\) is the total volume of cells near the axial location considered in \(m^3\)

  • \(\alpha_{\rm gas}\) is the gas phase volume fraction

  • \(U_{\rm gas}\) is the gas phase velocity along the axial direction in \(m.s^{-1}\)

  • \(V_{\rm height}\) is the local volume of the cells where \(U_{\rm gas} \alpha_{\rm gas}\) is measured (near the axial location considered) in \(m^3\)

With the paraview operations (use_pv==True)

\[\frac{1}{S_{\rm height, tot}} \int_{S_{\rm height}} U_{\rm gas} \alpha_{\rm gas} dS\]
where:
  • \(S_{\rm height, tot}\) is the total area of the slice at the axial location considered and normal tot the direction considered in \(m^2\)

  • \(\alpha_{\rm gas}\) is the gas phase volume fraction

  • \(U_{\rm gas}\) is the gas phase velocity along the axial direction in \(m.s^{-1}\)

  • \(S_{\rm height}\) is the local area of the slice where \(U_{\rm gas} \alpha_{\rm gas}\) is measured (near the axial location considered) in \(m^2\)

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • direction (int | None) – Direction along which to calculate the superficial velocity. If None, assume y direction

  • cell_centers_file (str | None) – Filename of cell center data If None, finds cell center file automatically

  • height (float | None) – Axial location at which to compute the superficial velocity. If None, use the mid point of the liquid domain along the axial direction

  • use_pv (bool) – Use paraview to create a slice in the middle of the reactor Default to False

  • field_dict (dict | None) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • sup_vel (float) – Superficial velocity (in m/s)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_turbulent_diffusivity(case_folder: str, time_folder: str, n_cells: int | None = None, field_dict: dict | None = None) → tuple[float, dict]

Liquid-averaged turbulent mass diffusivity.

\[D_{\rm turb} = \frac{\alpha_t^{\rm liq}}{\rho^{\rm liq}}\]

averaged over the liquid [m^2/s]. alphat.liquid already carries the solver’s turbulent Prandtl number; if it was not written, the field falls back to \(\nu_t^{\rm liq} / Pr_t\) with \(Pr_t = 0.85\). The density is read from thermo:rho.liquid (then rho.liquid), falling back to rho0MixLiq from globalVars and then 1000.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • turbulent_diffusivity (float) – Volume averaged turbulent mass diffusivity, in \(m^2.s^{-1}\)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.compute_weber_number(case_folder: str, time_folder: str, length: float, n_cells: int | None = None, volume_time: str | None = None, field_dict: dict | None = None) → tuple[float, dict]

Weber number from the liquid-averaged velocity/density and a given length.

\(We = \rho U^2 L / \sigma\) with \(U\) and \(\rho\) the liquid-volume-averaged velocity magnitude and density at time_folder, \(\sigma\) from constant/phaseProperties, and \(L\) the passed length.

Parameters:
  • case_folder (str) – Path to case folder

  • time_folder (str) – Name of the time folder to analyze

  • length (float) – Characteristic length \(L\), in \(m\)

  • n_cells (int | None) – Number of cells in the domain. If None, it will deduced from the field reading

  • volume_time (str | None) – Time folder to read to get the cell volumes. If None, finds volume time automatically

  • field_dict (dict) – Dictionary of fields used to avoid rereading the same fields to calculate different quantities

Returns:

  • weber_number (float) – Weber number (dimensionless)

  • field_dict (dict) – Dictionary of fields read

bird.postprocess.post_quantities.froude(velocity: float, length: float, gravity: float = 9.81) → float

Froude number \(Fr = U / \sqrt{g\,L}\).

Parameters:
  • velocity (float) – Characteristic velocity \(U\), in \(m.s^{-1}\)

  • length (float) – Characteristic length \(L\), in \(m\)

  • gravity (float) – Gravitational acceleration \(g\), in \(m.s^{-2}\)

Returns:

froude_number – Froude number (dimensionless)

Return type:

float

bird.postprocess.post_quantities.interfacial_area(gas_holdup: float, bubble_diam: float) → float

Gas-liquid interfacial area per unit volume \(a = 6\,\epsilon / d\).

Parameters:
  • gas_holdup (float) – Gas holdup \(\epsilon\) (dimensionless)

  • bubble_diam (float) – Bubble diameter \(d\), in \(m\)

Returns:

interfacial_area – Interfacial area \(a\), in \(m^{-1}\)

Return type:

float

bird.postprocess.post_quantities.propose_loop_boxes_block_rect(mesh_geometry: dict, rescale: float | None = None) → list[dict]

Candidate loop-direction boxes for a block-rectangular loop reactor.

Builds one box per mesh segment (leg) from bird.meshing.block_rect_mesh.from_block_rect_to_seg(). Each box spans the leg along its axis, trimmed half a block at each end so adjacent legs do not overlap and the ambiguous junction cells stay uncovered. The proposed direction is each leg’s own axis orientation (end - start).

The mesh scale is never inferred: the box coordinates are scaled by rescale, which the caller must set to the factor used to build the mesh (e.g. the transformPoints scale). A mismatch surfaces downstream as a zero-coverage error in build_loop_direction_field().

Parameters:
  • mesh_geometry (dict) – The "Geometry" dict from the case mesh.json

  • rescale (float | None) – Uniform scale factor applied to the box coordinates; None assumes 1.0 (base units)

Returns:

boxes – Box list consumable by build_loop_direction_field()

Return type:

list[dict]

bird.postprocess.post_quantities.sherwood(kl: float, length: float, diffusivity: float) → float

Sherwood number \(Sh = k_L\,L / D\).

Parameters:
  • kl (float) – Mass-transfer coefficient \(k_L\), in \(m.s^{-1}\)

  • length (float) – Characteristic length \(L\), in \(m\)

  • diffusivity (float) – Mass diffusivity \(D\), in \(m^2.s^{-1}\)

Returns:

sherwood_number – Sherwood number (dimensionless)

Return type:

float

bird.postprocess.post_quantities.weber(density: float, velocity: float, length: float, surface_tension: float) → float

Weber number \(We = \rho\,U^2\,L / \sigma\).

Parameters:
  • density (float) – Fluid density \(\rho\), in \(kg.m^{-3}\)

  • velocity (float) – Characteristic velocity \(U\), in \(m.s^{-1}\)

  • length (float) – Characteristic length \(L\), in \(m\)

  • surface_tension (float) – Surface tension \(\sigma\), in \(N.m^{-1}\)

Returns:

weber_number – Weber number (dimensionless)

Return type:

float

bird.postprocess.stats module

bird.postprocess.stats.calc_mean(time_series: ndarray, time_values: ndarray | None = None) → tuple[float, float]

Compute mean and the uncertainty about the mean, from a time-series

Following Trenberth, “Some Effects of Finite Sample Size and Persistence on Meteorological Statistics. Part I: Autocorrelations”, 1984 And Oliver et al., “Estimating uncertainties in statistics computed from direct numerical simulation”, 2014

Parameters:
  • time_series (np.ndarray) – Time series of the signal

  • time_values (np.ndarray | None) – The time values over which the time series is sampled. If None, the time values are assumed equally spaced. Otherwise, time_values is used to create a new equally spaced time_values

Returns:

  • mean_val (float) – Mean value of the time_series

  • unc_val (float) – 95% uncertainty (1.96 sigma) about the mean

bird.postprocess.stats.steady_stat(time_series: ndarray | list, time_values: ndarray | list, window: float | None = None) → tuple[float, float]

(mean, 1-sigma uncertainty) over the tail window of a time series.

The statistic is computed over the last window (in time units) of the series via the T0 estimator (calc_mean()), with its 95% (1.96 sigma) uncertainty converted to 1 sigma. window defaults to 10% of the total simulation time. Returns (nan, nan) for an empty or all-nan series and (value, 0.0) when a single sample falls in the window.

Parameters:
  • time_series (np.ndarray | list) – Time series of the signal

  • time_values (np.ndarray | list) – Sampling times of the series

  • window (float | None) – Length of the end window in time units. If None, 10% of the total time span is used

Returns:

  • mean_val (float) – Mean value over the tail window

  • unc_val (float) – 1-sigma uncertainty about the mean