turbo_moc.reporting module#

Shared console/file reporting for TurboMoC, its Gmsh and Fluent workflows.

Library modules only obtain loggers (logging.getLogger(__name__)) under the turbo_moc hierarchy (turbo_moc.api, turbo_moc.solvers.*, turbo_moc.meshing.*, turbo_moc.workflows.*); they never install handlers. An entry point opts in to output explicitly:

from turbo_moc import design_nozzle
from turbo_moc.reporting import logging_context

with logging_context("nozzle.log", level="INFO"):
    result = design_nozzle(...)

logging_context configures only the turbo_moc logger (console and, optionally, a fresh UTF-8 file), never the root logger, and restores the previous handlers, level and propagation on exit – also after exceptions and interruptions – so repeated runs neither duplicate records nor leak file handles. Without it, Python’s default applies: warnings and errors reach stderr, routine INFO progress stays silent.

Levels:

  • INFO – inputs, stage start/completion, throttled progress of long stages (at most once per second per stage) and a short result summary.

  • DEBUG – per-iteration diagnostics, adaptive step sizes, critical-state details, fluid-manager reuse. Computed only when DEBUG is enabled.

  • WARNING – recoverable failures, premature stops, fallbacks to the last valid state, non-converged results and automatic retries.

Progress callbacks (progress_callback(fraction, stage_label), e.g. for the Dash app) are driven by the same solver state as the log, but are delivered on every update regardless of the log level or console throttling. Fractions of counted loops are exact (work done / total); the conventional kernel reports the fraction of the initial gap to its termination target closed so far – an estimate of convergence, not of remaining runtime; the minimum-length kernel reports its prescribed angular sweep. Elapsed times use time.perf_counter at stage boundaries; they include first-call setup and JAX compilation where those happen (not measured separately).

class turbo_moc.reporting.ReportFormatter(width=100)[source]#

Bases: Formatter

Plain INFO messages, [LEVEL] prefixes otherwise; long lines are wrapped (not truncated) at LINE_WIDTH with an indented continuation. Words, paths and tracebacks are never broken.

Methods

converter([seconds])

Convert seconds since the Epoch to a time tuple expressing local time.

format(record)

Format the specified record as text.

formatException(ei)

Format and return the specified exception information as a string.

formatStack(stack_info)

This method is provided as an extension point for specialized formatting of stack information.

formatTime(record[, datefmt])

Return the creation time of the specified LogRecord as formatted text.

usesTime()

Check if the format uses the creation time of the record.

formatMessage

format(record)[source]#

Format the specified record as text.

The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

class turbo_moc.reporting.StageProgress(logger, index, title, label, callback=None, total=4, name=None, clock=<built-in function perf_counter>, interval=1.0)[source]#

Bases: object

Reporting for one MoC stage: a start line, at most one progress line per interval seconds, and one completion line with the elapsed time.

update(fraction, detail) forwards the clamped, monotonic fraction to the progress callback on every call (independent of the log level); detail – a string or a zero-argument callable, evaluated only when a line is actually logged – describes the measurements. clock is injectable for tests.

Attributes:
elapsed

Methods

finish([outcome])

Completion line, e.g. outcome "completed", "reached the target", "stopped early"; a completed stage reports fraction 1 to the callback.

begin

update

begin()[source]#
property elapsed#
finish(outcome='completed')[source]#

Completion line, e.g. outcome “completed”, “reached the target”, “stopped early”; a completed stage reports fraction 1 to the callback.

update(fraction, detail=None)[source]#
turbo_moc.reporting.display_path(path, base_dir=None)[source]#

path relative to base_dir (default: the working directory) when inside it, else absolute; always with forward slashes.

turbo_moc.reporting.format_pressure(p)[source]#

Readable pressure with its unit: Pa, kPa or MPa.

turbo_moc.reporting.get_logger(name)[source]#

Logger turbo_moc.<name> (for scripts and workflows outside the package).

turbo_moc.reporting.heading(logger, title)[source]#

Prominent top-level heading (workflow start, final results).

turbo_moc.reporting.logging_context(log_file=None, level='INFO', stream=None)[source]#

Send turbo_moc records to stream (default stdout) and, if given, a fresh UTF-8 log_file, each exactly once; restore everything on exit.

The root logger is untouched. An exception escaping the block is logged once here, with its traceback, and re-raised; Ctrl+C is reported as an interruption.

turbo_moc.reporting.section(logger, title)[source]#

Top-level workflow section.

turbo_moc.reporting.step(logger, number, total, title)[source]#

Announce a numbered top-level workflow step before starting it.

turbo_moc.reporting.summary(logger, title, values, indent='')[source]#

Aligned label/value block (caller supplies units), one blank line before.