pymm.core.pymm module#

Command-line entry point and top-level workflow coordination for pymm.

pymm supports four connected workflows for microsystem models:

  • Image processing segments grains, voids, and the external boundary.

  • Mesh generation creates Gmsh geometry and mesh files.

  • Flow simulation runs a steady incompressible OpenFOAM model.

  • Tracer simulation runs transient transport using the computed flow field.

This module parses and validates command-line arguments and TOML parameters, processes images, extracts and tags boundaries, writes mesh input, dispatches the selected simulations, and reports generated files. It also provides the shared terminal helpers used for errors, progress messages, and successful results.

class pymm.core.pymm.PymmConfig(length: float, width: float, thickness: float, grainMeaning: int, threshold: float, rescale: float, grainsSize: int, borderTol: float, grainsTol: float, lineWidth: float, channelWidth: float, meshSize: float, viscosity: float, diffusion: float, inletLocation: str, inletValue: float, tracerTime: float, tracerWrite: float, pressureConv: float, velocityConv: float, iterationsMax: int, tracerStep: float)[source]#

Bases: object

Store the shared pymm configuration loaded from TOML.

The top-level TOML values populate this frozen data class. The configuration is validated by check_toml() and then shared by the image, mesh, flow, and tracer workflows.

Attributes:
lengthfloat

Physical length used to scale the Gmsh geometry.

widthfloat

Physical width used to scale the Gmsh geometry.

thicknessfloat

Extrusion thickness used by the Gmsh template.

grainMeaningint

Grain convention: 0 for light grains or 1 for dark grains.

thresholdfloat

Grayscale segmentation threshold in the closed interval [0, 1].

rescalefloat

Positive image rescaling factor.

grainsSizeint

Maximum size, in pixels, of small grain objects to remove.

borderTolfloat

Polygon-approximation tolerance for the external boundary.

grainsTolfloat

Polygon-approximation tolerance for interior grains.

lineWidthfloat

Line width used in the diagnostic figures.

channelWidthfloat

Channel width passed to the Gmsh template.

meshSizefloat

Target mesh size passed to the Gmsh template.

viscosityfloat

Viscosity written to the OpenFOAM physical properties.

diffusionfloat

Tracer diffusion value written to the OpenFOAM case.

inletLocationstr

Inlet side: left, top, right, or bottom.

inletValuefloat

Inlet value written to the OpenFOAM pressure field.

tracerTimefloat

End time for the tracer simulation.

tracerWritefloat

Output interval for the tracer simulation.

pressureConvfloat

Pressure convergence tolerance for the flow solver.

velocityConvfloat

Velocity convergence tolerance for the flow solver.

iterationsMaxint

Maximum number of steady-flow iterations.

tracerStepfloat

Time step for the tracer simulation.

Notes

Physical units are defined by the Gmsh and OpenFOAM templates and must be consistent across the configuration.

borderTol: float#
channelWidth: float#
diffusion: float#
grainMeaning: int#
grainsSize: int#
grainsTol: float#
inletLocation: str#
inletValue: float#
iterationsMax: int#
length: float#
lineWidth: float#
meshSize: float#
pressureConv: float#
rescale: float#
thickness: float#
threshold: float#
tracerStep: float#
tracerTime: float#
tracerWrite: float#
velocityConv: float#
viscosity: float#
width: float#
pymm.core.pymm._assign_boundary(point: NDArray[float64], start_index: int, number_of_segments: int, reference_value: float, coordinate_index: int, target: list[int], wall: list[int]) int[source]#

Assign contour segments to an opening or wall.

Parameters:
pointnumpy.ndarray

Closed boundary-point array.

start_indexint

First segment index to inspect.

number_of_segmentsint

Number of consecutive segments to classify.

reference_valuefloat

Coordinate of the target image edge.

coordinate_indexint

Coordinate column used for comparison.

targetlist[int]

Target-boundary indices updated in place.

walllist[int]

Wall-boundary indices updated in place.

Returns:
int

First segment index after the processed range.

pymm.core.pymm._colorize(text: str, code: str, stream: object = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>) str[source]#

Wrap text in an ANSI color sequence when supported.

Parameters:
textstr

Text to format.

codestr

ANSI color code.

streamobject, optional

Output stream used to determine color support.

Returns:
str

Colored or unchanged text.

pymm.core.pymm._supports_color(stream: object = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>) bool[source]#

Check whether an output stream supports ANSI colors.

Parameters:
streamobject, optional

Output stream to inspect.

Returns:
bool

Whether ANSI color output is enabled.

pymm.core.pymm.boundary_tags_left_top(point: NDArray[float64], pl: NDArray[float64], pt: NDArray[float64], bl: float, bt: float, wall: list[int]) tuple[list[int], list[int], int][source]#

Assign boundary tags for the left and top edges.

Parameters:
pointnumpy.ndarray

Closed boundary-point array.

plnumpy.ndarray

Left-boundary points.

ptnumpy.ndarray

Top-boundary points.

blfloat

Left reference coordinate.

btfloat

Top reference coordinate.

walllist[int]

Wall indices updated in place.

Returns:
tuple[list[int], list[int], int]

Left tags, top tags, and the first unprocessed segment index.

pymm.core.pymm.boundary_tags_right_bottom(point: NDArray[float64], start_index: int, pr: NDArray[float64], pb: NDArray[float64], bb: float, br: float, wall: list[int]) tuple[list[int], list[int]][source]#

Assign boundary tags for the right and bottom edges.

Parameters:
pointnumpy.ndarray

Closed boundary-point array.

start_indexint

First segment index to inspect.

prnumpy.ndarray

Right-boundary points.

pbnumpy.ndarray

Bottom-boundary points.

bbfloat

Bottom reference coordinate.

brfloat

Right reference coordinate.

walllist[int]

Wall indices updated in place.

Returns:
tuple[list[int], list[int]]

Right and bottom boundary tags.

pymm.core.pymm.check_cmdargs(cmdargs: Namespace) None[source]#

Validate command-line values and incompatible operations.

Validation covers required paths, file extensions, mode-dependent image input, and Gmsh availability for workflows that generate a mesh.

Parameters:
cmdargsargparse.Namespace

Parsed command-line arguments.

Raises:
SystemExit

If an input value is invalid or a required executable is unavailable.

pymm.core.pymm.check_toml(cfg: PymmConfig) None[source]#

Validate the TOML configuration values.

Parameters:
cfgPymmConfig

Shared runtime configuration.

Raises:
SystemExit

If a value has an invalid type, range, or accepted value.

pymm.core.pymm.cli_correct_value(value: str) str[source]#

Format a valid CLI option or value.

Parameters:
valuestr

Accepted option, value, or example.

Returns:
str

Quoted value, colored green when supported.

pymm.core.pymm.cli_error_value(value: str) str[source]#

Format an invalid CLI option or value.

Parameters:
valuestr

Option or value to format.

Returns:
str

Quoted value, colored red when supported.

pymm.core.pymm.cli_info_value(value: str) str[source]#

Format an informational CLI option or value.

Parameters:
valuestr

Option or value to format.

Returns:
str

Quoted value, colored blue when supported.

pymm.core.pymm.copy_and_replace(src: Path, dst: Path, replacements: dict[str, Any]) None[source]#

Copy a text template and replace its placeholders.

Parameters:
srcpathlib.Path

Source template file.

dstpathlib.Path

Destination file.

replacementsdict[str, Any]

Literal placeholders and replacement values.

pymm.core.pymm.extract_borders(boundary: NDArray[float64]) tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64], float, float, float, float][source]#

Split the external contour into four image boundaries.

Parameters:
boundarynumpy.ndarray

Closed contour in padded-image coordinates.

Returns:
tuple

Left, top, right, and bottom point arrays followed by the four reference coordinates used for boundary tagging.

pymm.core.pymm.main(argv: list[str] | None = None) None[source]#

Run the pymm command-line workflow.

Parse and validate CLI arguments and TOML parameters, then dispatch the selected image, mesh, flow, and tracer operations.

Parameters:
argvlist[str] | None, optional

Arguments to parse instead of sys.argv[1:]. This is primarily used by tests and programmatic callers.

Raises:
SystemExit

If command-line or TOML validation fails.

tomllib.TOMLDecodeError

If the parameter file is not valid TOML.

subprocess.CalledProcessError

If an external command fails.

pymm.core.pymm.make_figures(cfg: PymmConfig, fol: Path, im: NDArray[bool], border: NDArray[bool], cn_grains: list[NDArray[float64]], cn_border: list[NDArray[float64]]) NDArray[float64][source]#

Create diagnostic figures for the grains and external boundary.

Parameters:
cfgPymmConfig

Shared runtime configuration.

folpathlib.Path

Output directory for generated figures.

imnumpy.ndarray

Padded binary image.

bordernumpy.ndarray

Boolean mask containing the external border.

cn_grainslist[numpy.ndarray]

Interior-grain contours in (row, column) order.

cn_borderlist[numpy.ndarray]

Candidate external-boundary contours.

Returns:
numpy.ndarray

Selected external boundary in reversed point order.

pymm.core.pymm.pad_with(vector: NDArray[float64], pad_width: tuple[int, int], _iaxis: int, kwargs: dict) None[source]#

Fill NumPy padding regions with a constant value.

Parameters:
vectornumpy.ndarray

One-dimensional array view modified in place.

pad_widthtuple[int, int]

Number of values padded before and after the original array.

_iaxisint

Axis supplied by numpy.pad(); unused.

kwargsdict

Callback options. padder selects the fill value.

pymm.core.pymm.parse_args(argv: list[str] | None = None) Namespace[source]#

Create the CLI parser and parse pymm arguments.

Parameters:
argvlist[str] | None, optional

Arguments to parse instead of sys.argv[1:].

Returns:
argparse.Namespace

Parsed command-line arguments.

pymm.core.pymm.process_image(cfg: PymmConfig, fol: Path, mode: str, in_image: str) tuple[int, int, list[NDArray[float64]], NDArray[float64]][source]#

Segment the input image and extract its contours.

Write diagnostic PNG files and return the rescaled dimensions, interior-grain contours, and external boundary.

Parameters:
cfgPymmConfig

Shared runtime configuration.

folpathlib.Path

Output directory for generated figures.

modestr

Microsystem setup, image or device.

in_imagestr

Path to the input PNG image.

Returns:
tuple[int, int, list[numpy.ndarray], numpy.ndarray]

Image height, image width, grain contours, and external boundary.

pymm.core.pymm.pymm_error(message: str) NoReturn[source]#

Raise a fatal pymm command-line error.

Parameters:
messagestr

Error message to display.

Raises:
SystemExit

Always raised with the formatted error message.

pymm.core.pymm.pymm_info(message: str) None[source]#

Display an informational pymm message.

Parameters:
messagestr

Progress or workflow message.

pymm.core.pymm.pymm_name(stream: object = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>) str[source]#

Format the pymm program name.

Parameters:
streamobject, optional

Output stream used to determine color support.

Returns:
str

Formatted program name.

pymm.core.pymm.pymm_success(msg: str, output_dir: str, filenames: list[str]) None[source]#

Display generated output files and locations.

Parameters:
msgstr

Optional success message.

output_dirstr

Directory containing the generated files.

filenameslist[str]

Generated filenames.

pymm.core.pymm.run_stokes(cfg: PymmConfig, fol: Path, pat: Path) None[source]#

Write and run the steady incompressible-flow case.

Create the OpenFOAM case, convert the Gmsh mesh, run the flow solver, export VTK results, and copy them to the pymm output directory.

Parameters:
cfgPymmConfig

Shared runtime configuration.

folpathlib.Path

Output directory containing mesh.msh.

patpathlib.Path

Project root containing the OpenFOAM templates.

Raises:
SystemExit

If gmshToFoam is unavailable.

subprocess.CalledProcessError

If an OpenFOAM command fails.

pymm.core.pymm.run_tracer(cfg: PymmConfig, fol: Path, pat: Path) None[source]#

Write and run the transient tracer-transport case.

Create the OpenFOAM case, copy the latest flow fields and mesh, run the tracer solver, export VTK results, and copy them to the pymm output directory.

Parameters:
cfgPymmConfig

Shared runtime configuration.

folpathlib.Path

Output directory containing a completed flow case.

patpathlib.Path

Project root containing the OpenFOAM templates.

Raises:
SystemExit

If topoSet is unavailable.

subprocess.CalledProcessError

If an OpenFOAM command fails.

pymm.core.pymm.write_geo(cfg: PymmConfig, fol: Path, pat: Path, mode: str, gmsh: str, imH: int, imL: int, cn_grains: list[NDArray[float64]], pl: NDArray[float64], pt: NDArray[float64], pr: NDArray[float64], pb: NDArray[float64], bdnL: list[int], bdnT: list[int], bdnR: list[int], bdnB: list[int], wall: list[int]) None[source]#

Write the Gmsh geometry file and generate the mesh.

Convert image contours to Gmsh points and physical boundaries, render the mode-specific Mako template, and execute Gmsh.

Parameters:
cfgPymmConfig

Shared runtime configuration.

folpathlib.Path

Output directory.

patpathlib.Path

Project root containing the templates.

modestr

Microsystem setup, image or device.

gmshstr

Gmsh executable or command.

imHint

Rescaled image height in pixels.

imLint

Rescaled image width in pixels.

cn_grainslist[numpy.ndarray]

Interior-grain contours.

pl, pt, pr, pbnumpy.ndarray

Left, top, right, and bottom boundary points.

bdnL, bdnT, bdnR, bdnBlist[int]

Segment indices for the physical boundaries.

walllist[int]

Segment indices for wall boundaries.

Raises:
subprocess.CalledProcessError

If Gmsh exits with a nonzero status.