Architecture
DifferentialLab is organized around clear subsystem boundaries:
config: validated environment and constantssolver: numerical engines and expression parsingplotting: matplotlib figure buildersfrontend: Tkinter dialogs and embeddingpipeline: orchestration for the standardSolvepathcomplex_problems: plugin-based specialized workflowstransforms: scalar transform toolsutils: shared infrastructure (logging, export, exceptions, update checks)
High-level project layout
src/
main_program.py
pipeline.py
config/
solver/
plotting/
transforms/
complex_problems/
frontend/
utils/
Standard solve path
EquationDialog -> ParametersDialog -> run_solver_pipeline
-> validation + parser + solver
-> statistics + export
-> ResultDialog
Key design goal: keep the general solver stack independent from UI-specific behavior.
Complex Problems architecture
complex_problems uses a lazy plugin registry.
Core pieces:
base.py:ProblemDescriptorandComplexProblemprotocolproblem_registry.py: lazy registration and dispatchcomplex_problems_dialog.py: selector windowcommon/: shared helpers for plugin modulesbackground execution (
run_solver_with_loading)safe expression compilation
numeric UI parsing helpers
Plugin contract:
problem.pyexposesPROBLEMwith descriptor +open_dialog(parent)ui.pygathers validated inputsolver.pyreturns structured result dataclassresult_dialog.pyrenders module-specific diagnosticsmodel.pyoptional physical/math helpers
Registered complex problem plugins
coupled_oscillatorsmembrane_2dnonlinear_wavesschrodinger_tdantenna_radiationaerodynamics_2dpipe_flow
Configuration lifecycle
main_program.pycallsinitialize_and_validate_config()..envis loaded and validated againstENV_SCHEMA.Invalid values are corrected to defaults and logged.
Runtime reads values through
get_env_from_schema(key).In-app
Configurationrewrites.envand restarts the app.
API and import strategy
Public APIs are re-exported in package
__init__.pyfiles.Heavy libraries are imported lazily where practical.
Internal modules import siblings directly to avoid circular re-export issues.
Error handling and safety
Expression inputs are AST-validated before evaluation.
Solver failures propagate as user-facing dialog errors, not hard crashes.
Plugin solvers run in background threads with loading/progress dialogs.
Extensibility principles
Keep numeric kernels separate from UI code.
Use result dataclasses with explicit fields (
metadata,magnitudes, raw fields).Add plugin modules without changing generic solver pipeline.
Register new plugins only in
problem_registry.py.