Common¶
Dependency-free primitives every stage shares: config areas, tags, vectors, protocols, logging, progress and console formatting.
femforge.common
¶
Dependency-free primitives shared by every stage: config areas, tags, vectors, protocols, logging, progress UI, and console formatting.
Modules:
-
cliâThe failure every
femforgesubcommand raises, shared so a command module needs no import back into the entry point. -
configâThe shared base of the config area models.
-
filesâThe run-bundle filename vocabulary every writer and the retention sweep share, plus the file primitives they use.
-
frameâThe solve frame: how an authored model maps onto the frame Elmer solves in.
-
introspectâSource-level reflection: the attribute docstrings an IDE shows on hover, read back at runtime.
-
logâThe only logging config site; every Rich output path (RichSink, StepTimer, tree prints) must share the one stderr Console from get_console().
-
namesâMemorable bundle names derived deterministically from the content hash:
<adjective>-<noun>-<hash8>. -
progressâProgress UI: live per-step elapsed-time rows rendered on the shared console.
-
protocolsâStructural typing contracts shared across pipeline stages.
-
pydanticâField-level
Annotatedmarkers read back by reflection:Map()ties a field to an external key name andHashExclude()keeps it out of a content hash. -
rich_sinkâRich-powered Loguru sink that renders each record as a fixed-column row via a Rich Console.
-
tagsâTags: the shared key vocabulary, tagged objects and the grouping of tagged items into hierarchies.
-
utilsâConsole formatting helpers: Rich color styles, Title Case labels and markup handling.
-
vectorâSmall geometric value types: 2D and 3D vectors, unit directions, boxes, quaternions and coordinate frames.
Type Aliases:
-
LevelsâThe tag keys to group by at each level, outermost first.
-
NestedâA leaf
Xor aTagGroupof nested nodes. -
TagDictâTag key=value pairs; a key is a
TagKeyor a user-defined name.
Classes:
-
ConfigAreaâShared base for the config area models:
arbitrary_types_allowedplususe_attribute_docstrings. -
StepTimerâContext manager showing a live elapsed-time line for one pipeline step.
-
TimerRenderableâLive-updating timer row; Rich calls
__rich__on every refresh tick. -
ElmerEmitterâSomething that emits its own Elmer sif keywords; materials, conditions, and boundaries all satisfy it.
-
MeshGroupSourceâSomething that resolves to one or more gmsh physical groups.
-
MapâAnnotatedmetadata marker tying a model field to an external key name. -
RichSinkâLoguru sink callable; add with
format="{message}"andcolorize=Falseso Rich owns all styling. -
CurrentDirâValues of
TagKey.CURRENT_DIR: whether an electrode part is a current entry or exit. -
HasTagsâA mixin that holds an object's tag key=value pairs.
-
TagGroupâA list of tagged items or nested groups that carries its own tags.
-
TagGrouperâGroups tagged items into a
TagGrouphierarchy, one level per list of tag keys. -
TagKeyâThe shared tag-key vocabulary: geometry authors these on parts, meshing/FEA select by them.
-
COLORSâFor use in rich console output. Not for physical materials.
-
BoxâAn axis-aligned 3D box spanned by its min and max corners.
-
CoordinateFrameâA position and orientation that maps local coordinates to global ones.
-
DirectionâA unit-length orientation, normalized and rounded on construction; arithmetic on it returns a plain Vec3.
-
QuaternionâA rotation quaternion
w + xi + yj + zk. -
RectâAn axis-aligned 2D rectangle spanned by its min and max corners.
-
Vec2âA mutable 2D vector.
-
Vec3âAn immutable 3D vector;
==andhashcompare its exact components.
Functions:
-
get_consoleâReturn the process-wide stderr Console shared by logging and all progress/tree rendering.
-
run_log_contextâBind
run_idinto the log context and write every record at DEBUG or above that carries it torun_dir/run.log. -
setup_loggingâInstall the terminal RichSink plus stdlib/warnings interception; repeat calls only adjust the sink level, library gates and telemetry root.
-
fmt_timeâFormat a duration in seconds as
m:ss.sors.s, right-justified towidth. -
get_map_keyâThe external key from a field's
Map()metadata, or None if the field carries noMap(). -
mapped_itemsâYield
(external_key, value)for each field carrying aMap()whose current value is not None. -
map_group_leavesâCollapse each deepest bucket of sibling leaves (a list[X]) into one Y,
-
map_leavesâTransform every leaf X -> Y, keeping the hierarchy identical.
-
parse_tagsâThe
key=valuepairs found in a label / STEP-name path; a repeated key keeps its last (deepest) value. -
contains_rich_markupâWhether
textlooks like it carries Rich markup. -
preserve_and_formatâPreserves existing string formatting and applies a new style safely.
-
titleâA label or identifier in Title Case: underscores and camelCase humps become spaces, acronyms are capitalized, joining words stay lower case.
Attributes:
-
DirectionFieldâA
Directionpydantic field, normalized on load. -
Vec3FieldâA
Vec3pydantic field, loaded from a Vec3,[x, y, z]or{x, y, z}.
DirectionField
module-attribute
¶
DirectionField = Direction
A Direction pydantic field, normalized on load.
Vec3Field
module-attribute
¶
Vec3Field = Vec3
A Vec3 pydantic field, loaded from a Vec3, [x, y, z] or {x, y, z}.
ConfigArea
pydantic-model
¶
Bases: BaseModel
Shared base for the config area models: arbitrary_types_allowed plus use_attribute_docstrings.
StepTimer
¶
Bases: Live
Context manager showing a live elapsed-time line for one pipeline step.
Parameters:
-
title(str) âThe step name.
-
msg(str, default:'') âA status message shown after the step name.
-
console(Console | None, default:None) âThe console to render on; None uses the shared one.
Source code in src/femforge/common/progress.py
TimerRenderable
¶
Bases: RichCast
Live-updating timer row; Rich calls __rich__ on every refresh tick.
Methods:
-
elapsedâSeconds since the timer started.
-
elapsed_strâThe elapsed time as
fmt_timeformats it.
Source code in src/femforge/common/progress.py
ElmerEmitter
¶
MeshGroupSource
¶
Bases: Protocol
Something that resolves to one or more gmsh physical groups.
Methods:
-
physical_group_nameâThe stable group name the Elmer side references the region by.
Map
¶
Map(map: str)
Annotated metadata marker tying a model field to an external key name.
Example: Annotated[bool, Map("Geometry.OCCImportLabels"), Field(...)] -- the gmsh option name lives on the field.
Source code in src/femforge/common/pydantic.py
RichSink
¶
RichSink(console: Console | None = None, *, time_format: str = '%H:%M:%S.%f', show_path: bool = True, path_width: int = 0, rich_tracebacks: bool = True, show_locals: bool = False, markup: bool = False, hide_keys: frozenset[str] = frozenset())
Loguru sink callable; add with format="{message}" and colorize=False so Rich owns all styling.
Parameters:
-
console(Console | None, default:None) âThe console to print to; None prints to a new stderr console.
-
time_format(str, default:'%H:%M:%S.%f') âThe
strftimeformat of the time column. -
show_path(bool, default:True) âShow the
module:functioncolumn. -
path_width(int, default:0) âTruncate the location column to this width, keeping its tail; 0 sizes it to its content.
-
rich_tracebacks(bool, default:True) âRender a logged exception as a Rich traceback.
-
show_locals(bool, default:False) âInclude local variables in Rich tracebacks.
-
markup(bool, default:False) âParse Rich markup in messages.
-
hide_keys(frozenset[str], default:frozenset()) âThe bound
extrakeys to leave out of the context column.
Source code in src/femforge/common/rich_sink.py
CurrentDir
¶
Bases: StrEnum
Values of TagKey.CURRENT_DIR: whether an electrode part is a current entry or exit.
Attributes:
HasTags
¶
HasTags(tags: TagDict | None = None)
A mixin that holds an object's tag key=value pairs.
Methods:
-
set_tagâSet
keyto the cleanedvalue. -
add_tagâSet
keyto the cleanedvalue, likeset_tag. -
get_tagâThe value of
key, ordefaultwhen it is unset. -
get_tagsâA copy of the tags, or of only
keyswith an unset key as an empty string. -
get_key_stringâReturn a string representation of the tags for the given keys.
-
remove_tagâDrop
keywhen it is set. -
clear_tagsâDrop every tag.
-
set_tagsâReplace every tag with
tags, each value cleaned. -
tags_strâThe tags as comma-separated
key=valuepairs.
Attributes:
-
current_tags(TagDict) âA copy of the tags.
Source code in src/femforge/common/tags.py
set_tag
¶
add_tag
¶
get_tag
¶
get_tags
¶
A copy of the tags, or of only keys with an unset key as an empty string.
Source code in src/femforge/common/tags.py
get_key_string
¶
Return a string representation of the tags for the given keys.
clear_tags
¶
TagGroup
¶
A list of tagged items or nested groups that carries its own tags.
Methods:
-
flattenâRoll the hierarchy up into a flat list of leaves, merging each path's tags onto the item (its own tags win only for keys the hierarchy doesn't set). Mutates
.tagsin place. -
treeâReturn a tree representation of the tag group.
Source code in src/femforge/common/tags.py
flatten
¶
flatten() -> list[X]
Roll the hierarchy up into a flat list of leaves, merging each path's tags onto the item (its own tags win only for keys the hierarchy doesn't set). Mutates .tags in place.
Source code in src/femforge/common/tags.py
tree
¶
Return a tree representation of the tag group.
Source code in src/femforge/common/tags.py
TagGrouper
¶
Bases: HasTags
Groups tagged items into a TagGroup hierarchy, one level per list of tag keys.
Methods:
-
then_byâA grouper with
keysadded as the next level. -
applyâGroup items into a single root TagGroup (root has empty tags).
-
mapâGroup
itemsand transform each leaf withfn. -
map_groupsâGroup
itemsand collapse each deepest bucket of leaves withfn.
Source code in src/femforge/common/tags.py
TagKey
¶
Bases: StrEnum
The shared tag-key vocabulary: geometry authors these on parts, meshing/FEA select by them.
Attributes:
-
MATERIALâThe registry tag of the body's material.
-
PHASEâThe winding phase a conductor belongs to.
-
CURRENT_DIRâWhether an electrode is a current entry or exit, a
CurrentDirvalue. -
SEGMENTâThe winding segment a conductor belongs to.
-
LAYERâThe layer a conductor lies on, such as a PCB copper layer.
-
TYPEâThe kind of part, such as
TraceorVia. -
MAGNETIZATIONâA magnet's magnetization label, such as
NorS. -
SLOTâThe pole or slot position a part occupies.
-
NAMEâThe authored part name; when set it is the body's name everywhere (mesh group, Elmer body, entities.json, viewer).
MATERIAL
class-attribute
instance-attribute
¶
The registry tag of the body's material.
PHASE
class-attribute
instance-attribute
¶
The winding phase a conductor belongs to.
CURRENT_DIR
class-attribute
instance-attribute
¶
Whether an electrode is a current entry or exit, a CurrentDir value.
SEGMENT
class-attribute
instance-attribute
¶
The winding segment a conductor belongs to.
LAYER
class-attribute
instance-attribute
¶
The layer a conductor lies on, such as a PCB copper layer.
MAGNETIZATION
class-attribute
instance-attribute
¶
A magnet's magnetization label, such as N or S.
NAME
class-attribute
instance-attribute
¶
The authored part name; when set it is the body's name everywhere (mesh group, Elmer body, entities.json, viewer).
COLORS
¶
For use in rich console output. Not for physical materials.
Methods:
-
gradientâGenerate
stepshex colors interpolating fromstart_colortoend_color. -
PropâFormat a property name/value pair with colors for rich console output.
-
PropNameâA property name in the property-name style.
-
PropValueâA property value in the property-value style.
-
H1âA top-level heading.
-
H2âA second-level heading.
-
H3âA third-level heading.
-
UnitsâA unit label in the units style.
gradient
staticmethod
¶
Generate steps hex colors interpolating from start_color to end_color.
Parameters:
-
start_color(str) âThe first color, as
#RRGGBB. -
end_color(str) âThe last color, as
#RRGGBB. -
steps(int) âHow many colors to generate.
Source code in src/femforge/common/utils.py
Prop
staticmethod
¶
Format a property name/value pair with colors for rich console output.
Source code in src/femforge/common/utils.py
Box
¶
CoordinateFrame
¶
CoordinateFrame(origin: Vec3, orientation: Quaternion)
A position and orientation that maps local coordinates to global ones.
Methods:
-
transform_positionâTransform a position from local to global coordinates
-
inverse_transform_positionâTransform a position from global to local coordinates
-
transform_directionâTransform a direction vector (ignoring translation) from local to global coordinates
-
inverse_transform_directionâTransform a direction vector (ignoring translation) from global to local coordinates
-
__mul__âCombine two coordinate frames by applying this transformation followed by the other
-
__rmul__âAllow left multiplication to combine coordinate frames
-
__imul__âIn-place combination of coordinate frames
Source code in src/femforge/common/vector.py
transform_position
¶
Transform a position from local to global coordinates
inverse_transform_position
¶
Transform a position from global to local coordinates
Source code in src/femforge/common/vector.py
transform_direction
¶
Transform a direction vector (ignoring translation) from local to global coordinates
inverse_transform_direction
¶
Transform a direction vector (ignoring translation) from global to local coordinates
Source code in src/femforge/common/vector.py
__mul__
¶
__mul__(other: CoordinateFrame) -> CoordinateFrame
Combine two coordinate frames by applying this transformation followed by the other
Source code in src/femforge/common/vector.py
__rmul__
¶
__rmul__(other: CoordinateFrame) -> CoordinateFrame
__imul__
¶
__imul__(other: CoordinateFrame) -> CoordinateFrame
In-place combination of coordinate frames
Direction
¶
Bases: Vec3
A unit-length orientation, normalized and rounded on construction; arithmetic on it returns a plain Vec3.
Parameters:
-
x(float) âThe x component of any non-zero vector along the direction.
-
y(float) âThe y component.
-
z(float) âThe z component.
Source code in src/femforge/common/vector.py
Quaternion
¶
A rotation quaternion w + xi + yj + zk.
Parameters:
-
w(float) âThe scalar part.
-
x(float) âThe i component.
-
y(float) âThe j component.
-
z(float) âThe k component.
Methods:
-
__mul__âHamilton product of two quaternions
-
conjugateâConjugate of the quaternion
-
magnitudeâThe Euclidean norm of the quaternion.
-
normalizedâThe unit quaternion with the same orientation; raises
ValueErrorfor a zero quaternion. -
rotate_vectorâRotate a vector by this quaternion
-
to_rotation_matrixâConvert the quaternion to a 3x3 rotation matrix
-
to_euler_anglesâConvert the quaternion to Euler angles (yaw, pitch, roll) in degrees
-
from_euler_anglesâCreate a quaternion from Euler angles in degrees.
-
from_axis_angleâCreate a quaternion from an axis and angle in degrees
-
slerpâSpherical linear interpolation between two quaternions.
Source code in src/femforge/common/vector.py
__mul__
¶
__mul__(other: Quaternion) -> Quaternion
Hamilton product of two quaternions
Source code in src/femforge/common/vector.py
conjugate
¶
conjugate() -> Quaternion
normalized
¶
normalized() -> Quaternion
The unit quaternion with the same orientation; raises ValueError for a zero quaternion.
Source code in src/femforge/common/vector.py
rotate_vector
¶
Rotate a vector by this quaternion
to_rotation_matrix
¶
Convert the quaternion to a 3x3 rotation matrix
Source code in src/femforge/common/vector.py
to_euler_angles
¶
Convert the quaternion to Euler angles (yaw, pitch, roll) in degrees
Source code in src/femforge/common/vector.py
from_euler_angles
staticmethod
¶
Create a quaternion from Euler angles in degrees.
Parameters:
-
yaw(float) âThe rotation about Z, in degrees.
-
pitch(float) âThe rotation about Y, in degrees.
-
roll(float) âThe rotation about X, in degrees.
Source code in src/femforge/common/vector.py
from_axis_angle
staticmethod
¶
from_axis_angle(axis: Vec3, angle_degrees: float) -> Quaternion
Create a quaternion from an axis and angle in degrees
Source code in src/femforge/common/vector.py
slerp
staticmethod
¶
slerp(q1: Quaternion, q2: Quaternion, t: float) -> Quaternion
Spherical linear interpolation between two quaternions.
Parameters:
-
q1(Quaternion) âThe orientation at
t = 0. -
q2(Quaternion) âThe orientation at
t = 1. -
t(float) âThe interpolation fraction.
Source code in src/femforge/common/vector.py
Rect
¶
Vec2
¶
A mutable 2D vector.
Methods:
-
rotateâRotate the vector by a given angle in degrees around a center point
-
magnitudeâEuclidean length of the vector.
-
to_listâThe components as
[x, y]. -
to_tupleâThe components as
(x, y).
Source code in src/femforge/common/vector.py
rotate
¶
Rotate the vector by a given angle in degrees around a center point
Source code in src/femforge/common/vector.py
to_list
¶
Vec3
dataclass
¶
An immutable 3D vector; == and hash compare its exact components.
Methods:
-
iscloseâWhether every component matches
otherwithintolerance, relative or absolute. -
magnitudeâEuclidean length |v| of the vector.
-
dotâThe scalar product with
other. -
normalizedâA unit vector in the same direction; raises
ValueErrorfor a zero-length vector. -
to_listâThe components as
[x, y, z]. -
to_tupleâThe components as
(x, y, z).
Attributes:
-
x(float) âx[?]: The x component. -
y(float) ây[?]: The y component. -
z(float) âz[?]: The z component.
isclose
¶
Whether every component matches other within tolerance, relative or absolute.
Source code in src/femforge/common/vector.py
dot
¶
normalized
¶
normalized() -> Vec3
A unit vector in the same direction; raises ValueError for a zero-length vector.
Source code in src/femforge/common/vector.py
to_list
¶
get_console
¶
Return the process-wide stderr Console shared by logging and all progress/tree rendering.
run_log_context
¶
Bind run_id into the log context and write every record at DEBUG or above that carries it to run_dir/run.log.
Source code in src/femforge/common/log.py
setup_logging
¶
setup_logging(*, level: LogLevel | str | None = None, console: Console | None = None, library_levels: Mapping[str, LogLevel | str] | None = None, telemetry: Path | None = None, process: str | None = None) -> None
Install the terminal RichSink plus stdlib/warnings interception; repeat calls only adjust the sink level, library gates and telemetry root.
Parameters:
-
level(LogLevel | str | None, default:None) âTerminal sink threshold;
Nonefalls back to theFEMFORGE_LOG_LEVELenv var, thenINFO. -
console(Console | None, default:None) âConsole the sink renders into;
Noneuses the shared stderr console fromget_console(). -
library_levels(Mapping[str, LogLevel | str] | None, default:None) âStdlib logger name to minimum level, gating chatty libraries at the source;
NoneappliesDEFAULT_LIBRARY_LEVELS. -
telemetry(Path | None, default:None) âTelemetry root the parquet sink writes to;
Nonefalls back toFEMFORGE_TELEMETRY, and telemetry stays off when that is unset too. -
process(str | None, default:None) âName the telemetry rows are partitioned under;
Noneuses the sanitizedsys.argv[0]stem.
Source code in src/femforge/common/log.py
fmt_time
¶
Format a duration in seconds as m:ss.s or s.s, right-justified to width.
Source code in src/femforge/common/progress.py
get_map_key
¶
The external key from a field's Map() metadata, or None if the field carries no Map().
Source code in src/femforge/common/pydantic.py
mapped_items
¶
Yield (external_key, value) for each field carrying a Map() whose current value is not None.
Source code in src/femforge/common/pydantic.py
map_group_leaves
¶
Collapse each deepest bucket of sibling leaves (a list[X]) into one Y, keeping its enclosing group and tags.
Source code in src/femforge/common/tags.py
map_leaves
¶
Transform every leaf X -> Y, keeping the hierarchy identical.
parse_tags
¶
The key=value pairs found in a label / STEP-name path; a repeated key keeps its last (deepest) value.
contains_rich_markup
¶
Whether text looks like it carries Rich markup.
Source code in src/femforge/common/utils.py
preserve_and_format
¶
Preserves existing string formatting and applies a new style safely.
Source code in src/femforge/common/utils.py
title
¶
A label or identifier in Title Case: underscores and camelCase humps become spaces, acronyms are capitalized, joining words stay lower case.