# PathSim Documentation (Full) > PathSim is a Python framework for simulating dynamical systems using block diagrams. It supports continuous-time, discrete-time, and hybrid systems with 18+ numerical solvers, hierarchical subsystems, event handling, and MIMO connections. ## Installation ```bash pip install pathsim pip install pathsim-chem # Chemical engineering toolbox pip install pathsim-rf # RF/microwave toolbox ``` ## PathSim (v0.19.0) ### Quickstart From the [Harmonic Oscillator](https://docs.pathsim.org/pathsim/v0.19.0/examples/harmonic-oscillator) example: ```python import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Integrator, Amplifier, Adder, Scope # Initial position and velocity x0, v0 = 2, 5 # Parameters (mass, damping, spring constant) m, c, k = 0.8, 0.2, 1.5 # Blocks that define the system I1 = Integrator(v0) # integrator for velocity I2 = Integrator(x0) # integrator for position A1 = Amplifier(c) A2 = Amplifier(k) A3 = Amplifier(-1/m) P1 = Adder() Sc = Scope(labels=["velocity", "position"]) blocks = [I1, I2, A1, A2, A3, P1, Sc] # The connections between the blocks connections = [ Connection(I1, I2, A1, Sc), Connection(I2, A2, Sc[1]), Connection(A1, P1), Connection(A2, P1[1]), Connection(P1, A3), Connection(A3, I1) ] # Initialize simulation with the blocks, connections, timestep Sim = Simulation(blocks, connections, dt=0.01, log=True) # Run the simulation for 25 seconds Sim.run(duration=25) # Plot the results from the scope ``` ### API Reference #### pathsim.connection ##### class Connection Class to handle input-output relations of blocks by connecting them (directed graph) **Parameters:** - `source` — source block and optional source output port - `targets, default=()` — target blocks and optional target input ports **Attributes:** - `source` - `targets` **Connection.__init__**`(source, targets = ())` - `source` - `targets, default=()` **Connection.get_blocks**`()` : Returns all the unique internal source and target blocks **Connection.on**`()` **Connection.off**`()` **Connection.update**`()` : Transfers data from the source block output port ##### class Duplex(pathsim.connection.Connection) Extension of the 'Connection' class, that defines bidirectional **Parameters:** - `source` - `target` **Attributes:** - `source` - `target` - `targets` **Duplex.__init__**`(source, target)` - `source` - `target` **Duplex.update**`()` : Transfers data between the two target blocks #### pathsim.simulation ##### class Simulation Class that performs transient analysis of the dynamical system, defined by the **Parameters:** - `blocks, default=None` — blocks that define the system - `connections, default=None` — connections that connect the blocks - `events, default=None` — list of event trackers (zero crossing detection, schedule, etc.) - `dt, default=SIM_TIMESTEP` — transient simulation timestep in time units, default see ´SIM_TIMESTEP´ in ´_constants.py´ - `dt_min, default=SIM_TIMESTEP_MIN` — lower bound for transient simulation timestep, default see ´SIM_TIMESTEP_MIN´ in ´_constants.py´ - `dt_max, default=SIM_TIMESTEP_MAX` — upper bound for transient simulation timestep, default see ´SIM_TIMESTEP_MAX´ in ´_constants.py´ - `Solver, default=SSPRK22` — ODE solver class for numerical integration from ´pathsim.solvers´, default is ´pathsim.solvers.ssprk22.SSPRK22´ (2nd order expl. Runge Kutta) - `tolerance_fpi, default=SIM_TOLERANCE_FPI` — absolute tolerance for convergence of algebraic loops and internal optimizers of implicit ODE solvers, default see ´SIM_TOLERANCE_FPI´ in ´_constants.py´ - `iterations_max, default=SIM_ITERATIONS_MAX` — maximum allowed number of iterations for implicit ODE solver optimizers and algebraic loop solver, default see ´SIM_ITERATIONS_MAX´ in ´_constants.py´ - `log, default=LOG_ENABLE` — flag to enable logging, default see ´LOG_ENABLE´ in ´_constants.py´ (alternatively a path to a log file can be specified) - `solver_kwargs, default={}` — additional parameters for numerical solvers such as absolute (´tolerance_lte_abs´) and relative (´tolerance_lte_rel´) tolerance, defaults are defined in ´_constants.py´ **Attributes:** - `blocks` - `connections` - `events` - `dt` - `dt_min` - `dt_max` - `Solver` - `engine` - `graph` - `boosters` - `tolerance_fpi` - `solver_kwargs` - `iterations_max` - `log` - `time` - `logger` - `size` — Get size information of the simulation, such as total number **Simulation.__init__**`(blocks = None, connections = None, events = None, dt = SIM_TIMESTEP, dt_min = SIM_TIMESTEP_MIN, dt_max = SIM_TIMESTEP_MAX, Solver = SSPRK22, tolerance_fpi = SIM_TOLERANCE_FPI, iterations_max = SIM_ITERATIONS_MAX, log = LOG_ENABLE, solver_kwargs = {})` - `blocks, default=None` - `connections, default=None` - `events, default=None` - `dt, default=SIM_TIMESTEP` - `dt_min, default=SIM_TIMESTEP_MIN` - `dt_max, default=SIM_TIMESTEP_MAX` - `Solver, default=SSPRK22` - `tolerance_fpi, default=SIM_TOLERANCE_FPI` - `iterations_max, default=SIM_ITERATIONS_MAX` - `log, default=LOG_ENABLE` - `solver_kwargs, default={}` **Simulation.plot**`(args = (), kwargs = {})` : Plot the simulation results by calling all the blocks - `args, default=()` — args for the plot methods - `kwargs, default={}` — kwargs for the plot method **Simulation.save_checkpoint**`(path, recordings = True)` : Save simulation state to checkpoint files (JSON + NPZ). - `path` — base path without extension - `recordings, default=True` — include scope/spectrum recording data (default: True) **Simulation.load_checkpoint**`(path)` : Load simulation state from checkpoint files (JSON + NPZ). - `path` — base path without extension **Simulation.add_block**`(block)` : Adds a new block to the simulation, initializes its local solver - `block` — block to add to the simulation **Simulation.remove_block**`(block)` : Removes a block from the simulation. - `block` — block to remove from the simulation **Simulation.add_connection**`(connection)` : Adds a new connection to the simulation and checks if - `connection` — connection to add to the simulation **Simulation.remove_connection**`(connection)` : Removes a connection from the simulation. - `connection` — connection to remove from the simulation **Simulation.add_event**`(event)` : Checks and adds a new event to the simulation. - `event` — event to add to the simulation **Simulation.remove_event**`(event)` : Removes an event from the simulation. - `event` — event to remove from the simulation **Simulation.reset**`(time = 0.0)` : Reset the blocks to their initial state and the global time of - `time, default=0.0` — simulation time for reset **Simulation.linearize**`()` : Linearize the full system in the current simulation state **Simulation.delinearize**`()` : Revert the linearization of the full system. **Simulation.steadystate**`(reset = False)` : Find steady state solution (DC operating point) of the system - `reset, default=False` — reset the simulation before solving for steady state (default False) **Simulation.timestep_fixed_explicit**`(dt = None)` : Advances the simulation by one timestep 'dt' for explicit fixed step solvers. - `dt, default=None` — timestep **Simulation.timestep_fixed_implicit**`(dt = None)` : Advances the simulation by one timestep 'dt' for implicit fixed step solvers. - `dt, default=None` — timestep **Simulation.timestep_adaptive_explicit**`(dt = None)` : Advances the simulation by one timestep 'dt' for explicit adaptive solvers. - `dt, default=None` — timestep **Simulation.timestep_adaptive_implicit**`(dt = None)` : Advances the simulation by one timestep 'dt' for implicit adaptive solvers. - `dt, default=None` — timestep **Simulation.timestep**`(dt = None, adaptive = True)` : Advances the transient simulation by one timestep 'dt'. - `dt, default=None` — timestep size for transient simulation - `adaptive, default=True` — explicitly enable/disable adaptive timestepping; when False, adaptive solvers are forced to take fixed steps without error control (default True) **Simulation.step**`(dt = None, adaptive = True)` : Wraps 'Simulation.timestep' for backward compatibility - `dt, default=None` - `adaptive, default=True` **Simulation.collect**`()` : Collect all current simulation results from the internal **Simulation.stop**`()` : Set the flag for active simulation to 'False', intended to be **Simulation.run**`(duration = 10, reset = False, adaptive = True)` : Perform multiple simulation timesteps for a given 'duration'. - `duration, default=10` — simulation time (in time units) - `reset, default=False` — reset the simulation before running (default False) - `adaptive, default=True` — use adaptive timesteps if solver is adaptive (default True) **Simulation.run_streaming**`(duration = 10, reset = False, adaptive = True, tickrate = 10, func_callback = None)` : Perform simulation with streaming output at a fixed wall-clock rate. - `duration, default=10` — simulation time (in time units) - `reset, default=False` — reset the simulation before running (default False) - `adaptive, default=True` — use adaptive timesteps if solver is adaptive (default True) - `tickrate, default=10` — output rate in Hz, i.e., yields per second of wall-clock time (default 10) - `func_callback, default=None` — callback function that is called at every tick, can be used for data extraction, its return value is yielded by this generator **Simulation.run_realtime**`(duration = 10, reset = False, adaptive = True, tickrate = 30, speed = 1.0, func_callback = None)` : Perform simulation paced to wall-clock time. - `duration, default=10` — simulation time (in time units) - `reset, default=False` — reset the simulation before running (default False) - `adaptive, default=True` — use adaptive timesteps if solver is adaptive (default True) - `tickrate, default=30` — output rate in Hz, i.e., yields per second of wall-clock time (default 30) - `speed, default=1.0` — time scaling factor where 1.0 is real-time, 2.0 is twice as fast, 0.5 is half speed (default 1.0) - `func_callback, default=None` — callback function that is called at every tick, can be used for data extraction, its return value is yielded by this generator #### pathsim.subsystem ##### class Interface(pathsim.blocks._block.Block) Bare-bone block that serves as a data interface for the 'Subsystem' class. **Interface.register_port_map**`(port_map_in, port_map_out)` : Update the input and output registers of the interface block with port mappings - `port_map_in` — port alias mapping for block inputs - `port_map_out` — port alias mapping for block outputs ##### class Subsystem(pathsim.blocks._block.Block) Subsystem class that holds its own blocks and connecions and **Parameters:** - `blocks, default=None` — internal blocks of the subsystem - `connections, default=None` — internal connections of the subsystem - `events, default=None` - `tolerance_fpi, default=SIM_TOLERANCE_FPI` — absolute tolerance for convergence of algebraic loops default see ´SIM_TOLERANCE_FPI´ in ´_constants.py´ - `iterations_max, default=SIM_ITERATIONS_MAX` — maximum allowed number of iterations for algebraic loop solver, default see ´SIM_ITERATIONS_MAX´ in ´_constants.py´ **Attributes:** - `engine` - `tolerance_fpi` - `iterations_max` - `op_alg` - `op_dyn` - `graph` - `boosters` - `connections` - `blocks` - `interface` - `size` — Get size information from subsystem, recursively assembled - `events` — Recursively collect and return events spawned by the - `inputs` - `outputs` **Subsystem.__init__**`(blocks = None, connections = None, events = None, tolerance_fpi = SIM_TOLERANCE_FPI, iterations_max = SIM_ITERATIONS_MAX)` - `blocks, default=None` - `connections, default=None` - `events, default=None` - `tolerance_fpi, default=SIM_TOLERANCE_FPI` - `iterations_max, default=SIM_ITERATIONS_MAX` **Subsystem.add_block**`(block)` : Adds a new block to the subsystem. - `block` — block to add to the subsystem **Subsystem.remove_block**`(block)` : Removes a block from the subsystem. - `block` — block to remove from the subsystem **Subsystem.add_connection**`(connection)` : Adds a new connection to the subsystem. - `connection` — connection to add to the subsystem **Subsystem.remove_connection**`(connection)` : Removes a connection from the subsystem. - `connection` — connection to remove from the subsystem **Subsystem.add_event**`(event)` : Adds an event to the subsystem. - `event` — event to add to the subsystem **Subsystem.remove_event**`(event)` : Removes an event from the subsystem. - `event` — event to remove from the subsystem **Subsystem.plot**`(args = (), kwargs = {})` : Plot the simulation results by calling all the blocks - `args, default=()` — args for the plot methods - `kwargs, default={}` — kwargs for the plot method **Subsystem.collect**`()` : Aggregate results from internal blocks. **Subsystem.reset**`()` : Reset the subsystem interface and all internal blocks **Subsystem.to_checkpoint**`(prefix, recordings = False)` : Serialize subsystem state by recursively checkpointing internal blocks. - `prefix` — key prefix for NPZ arrays (assigned by simulation) - `recordings, default=False` — include recording data (for Scope blocks) **Subsystem.load_checkpoint**`(prefix, json_data, npz)` : Restore subsystem state by recursively loading internal blocks. - `prefix` — key prefix for NPZ arrays (assigned by simulation) - `json_data` — subsystem metadata from checkpoint JSON - `npz` — numpy arrays from checkpoint NPZ **Subsystem.on**`()` : Activate the subsystem and all internal blocks, sets the boolean **Subsystem.off**`()` : Deactivate the subsystem and all internal blocks, sets the boolean **Subsystem.linearize**`(t)` : Linearize the algebraic and dynamic components of the internal blocks. - `t` — evaluation time **Subsystem.delinearize**`()` : Revert the linearization of the internal blocks. **Subsystem.sample**`(t, dt)` : Update the internal connections again and sample data from - `t` — evaluation time - `dt` — integration timestep **Subsystem.update**`(t)` : Update the instant time components of the internal blocks - `t` — evaluation time **Subsystem.solve**`(t, dt)` : Advance solution of implicit update equation - `t` — evaluation time - `dt` — timestep **Subsystem.step**`(t, dt)` : Explicit component of timestep for internal blocks - `t` — evaluation time - `dt` — timestep **Subsystem.set_solver**`(Solver, parent, solver_args = {})` : Initialize all blocks with solver for numerical integration - `Solver` — numerical solver definition - `parent` — numerical solver instance as parent - `solver_args, default={}` — args to initialize solver with **Subsystem.revert**`()` : revert the internal blocks to the state **Subsystem.buffer**`(dt)` : buffer internal states of blocks with - `dt` — evaluation time for buffering #### pathsim.blocks._block ##### class Block Base 'Block' object that defines the inputs, outputs and the block interface. **Attributes:** - `input_port_labels` - `output_port_labels` - `inputs` - `outputs` - `engine` - `events` - `op_alg` - `op_dyn` - `size` — Get size information from block, such as - `shape` — Get the number of input and output ports of the block - `state` — Expose the state of the internal integration engine / **Block.__init__**`()` **Block.info**`(cls)` : Get block metadata for introspection and UI integration. **Block.plot**`(args = (), kwargs = {})` : Block specific visualization, enables plotting - `args, default=()` — args for the plot methods - `kwargs, default={}` — kwargs for the plot method **Block.on**`()` : Activate the block and all internal events, sets the boolean **Block.off**`()` : Deactivate the block and all internal events, sets the boolean **Block.reset**`()` : Reset the blocks inputs and outputs and also its internal solver, **Block.linearize**`(t)` : Linearize the algebraic and dynamic components of the block. - `t` — evaluation time **Block.delinearize**`()` : Revert the linearization of the blocks algebraic and dynamic components. **Block.set_solver**`(Solver, parent, solver_args = {})` : Initialize the numerical integration engine with local truncation error - `Solver` — numerical integrator class - `parent` — numerical integrator instance for stage synchronization - `solver_args, default={}` — additional args for the solver **Block.revert**`()` : Revert the block to the state of the previous timestep, if the **Block.buffer**`(dt)` : Buffer current internal state of the block and the current timestep - `dt` — integration timestep **Block.sample**`(t, dt)` : Samples the data of the blocks inputs or internal state when called. - `t` — evaluation time for sampling - `dt` — integration timestep **Block.read**`()` : Read data from recording blocks. **Block.collect**`()` : Yield (category, id, data) tuples for recording blocks to simplify **Block.get_all**`()` : Retrieves and returns internal states of engine (if available) **Block.to_checkpoint**`(prefix, recordings = False)` : Serialize block state for checkpointing. - `prefix` — key prefix for NPZ arrays (assigned by simulation) - `recordings, default=False` — include recording data (for Scope blocks) **Block.load_checkpoint**`(prefix, json_data, npz)` : Restore block state from checkpoint. - `prefix` — key prefix for NPZ arrays (assigned by simulation) - `json_data` — block metadata from checkpoint JSON - `npz` — numpy arrays from checkpoint NPZ **Block.update**`(t)` : The 'update' method is called iteratively for all blocks to evaluate the - `t` — evaluation time **Block.solve**`(t, dt)` : The 'solve' method performs one iterative solution step that is required - `t` — evaluation time - `dt` — integration timestep **Block.step**`(t, dt)` : The 'step' method is used in transient simulations and performs an action - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.adder ##### class Adder(pathsim.blocks._block.Block) Summs / adds up all input signals to a single output signal (MISO) **Parameters:** - `operations, default=None` — optional string of operations to be applied before summation, i.e. '+-' will compute the difference, 'None' will just perform regular sum **Attributes:** - `input_port_labels` - `output_port_labels` - `operations` - `op_alg` **Adder.__init__**`(operations = None)` - `operations, default=None` **Adder.update**`(t)` : update system equation in fixed point loop for - `t` — evaluation time #### pathsim.blocks.amplifier ##### class Amplifier(pathsim.blocks._block.Block) Amplifies the input signal by multiplication with a constant gain term. **Parameters:** - `gain, default=1.0` — amplifier gain **Attributes:** - `gain` - `op_alg` **Amplifier.__init__**`(gain = 1.0)` - `gain, default=1.0` **Amplifier.update**`(t)` : update system equation in fixed point loop - `t` — evaluation time #### pathsim.blocks.comparator ##### class Comparator(pathsim.blocks._block.Block) Comparator block that sets output depending on predefined thresholds for the input. **Parameters:** - `threshold, default=0` — threshold value for the comparator - `tolerance, default=0.0001` — tolerance for zero crossing detection - `span, default=[-1, 1]` — output value range [min, max] **Attributes:** - `input_port_labels` - `output_port_labels` - `threshold` - `tolerance` - `span` - `events` **Comparator.__init__**`(threshold = 0, tolerance = 0.0001, span = [-1, 1])` - `threshold, default=0` - `tolerance, default=0.0001` - `span, default=[-1, 1]` **Comparator.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time #### pathsim.blocks.converters ##### class ADC(pathsim.blocks._block.Block) Models an ideal Analog-to-Digital Converter (ADC). **Parameters:** - `n_bits, default=4` — Number of bits for the digital output code. Default is 4. - `span, default=[-1, 1]` — The valid analog input value range [min_voltage, max_voltage]. Inputs outside this range will be clipped. Default is [-1, 1]. - `T, default=1` — Sampling period (time between samples). Default is 1 time unit. - `tau, default=0` — Initial delay before the first sample is taken. Default is 0. **Attributes:** - `input_port_labels` - `output_port_labels` - `n_bits` - `span` - `T` - `tau` - `events` **ADC.__init__**`(n_bits = 4, span = [-1, 1], T = 1, tau = 0)` - `n_bits, default=4` - `span, default=[-1, 1]` - `T, default=1` - `tau, default=0` ##### class DAC(pathsim.blocks._block.Block) Models an ideal Digital-to-Analog Converter (DAC). **Parameters:** - `n_bits, default=4` — Number of digital input bits expected. Default is 4. - `span, default=[-1, 1]` — The analog output value range [min_voltage, max_voltage] corresponding to the digital codes 0 and 2^n_bits - 1, respectively (approximately). Default is [-1, 1]. - `T, default=1` — Update period (time between output updates). Default is 1 time unit. - `tau, default=0` — Initial delay before the first output update. Default is 0. **Attributes:** - `input_port_labels` - `output_port_labels` - `n_bits` - `span` - `T` - `tau` - `events` **DAC.__init__**`(n_bits = 4, span = [-1, 1], T = 1, tau = 0)` - `n_bits, default=4` - `span, default=[-1, 1]` - `T, default=1` - `tau, default=0` #### pathsim.blocks.counter ##### class Counter(pathsim.blocks._block.Block) Counts the number of detected bidirectional threshold crossings. **Parameters:** - `start, default=0` — counter start (initial condition) - `threshold, default=0.0` — threshold for zero crossing **Attributes:** - `input_port_labels` - `output_port_labels` - `start` - `threshold` - `E` - `events` **Counter.__init__**`(start = 0, threshold = 0.0)` - `start, default=0` - `threshold, default=0.0` **Counter.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time ##### class CounterUp(pathsim.blocks.counter.Counter) Counts the number of detected unidirectional (lo->hi) threshold crossings. **Parameters:** - `start, default=0` — counter start (initial condition) - `threshold, default=0.0` — threshold for zero crossing **Attributes:** - `E` - `events` **CounterUp.__init__**`(start = 0, threshold = 0.0)` - `start, default=0` - `threshold, default=0.0` ##### class CounterDown(pathsim.blocks.counter.Counter) Counts the number of detected unidirectional (hi->lo) threshold crossings. **Parameters:** - `start, default=0` — counter start (initial condition) - `threshold, default=0.0` — threshold for zero crossing **Attributes:** - `E` - `events` **CounterDown.__init__**`(start = 0, threshold = 0.0)` - `start, default=0` - `threshold, default=0.0` #### pathsim.blocks.ctrl ##### class PT1(pathsim.blocks.lti.StateSpace) First-order lag element (PT1). **Parameters:** - `K, default=1.0` — static gain - `T, default=1.0` — time constant in seconds (must be > 0) **Attributes:** - `input_port_labels` - `output_port_labels` - `K` - `T` **PT1.__init__**`(K = 1.0, T = 1.0)` - `K, default=1.0` - `T, default=1.0` ##### class PT2(pathsim.blocks.lti.StateSpace) Second-order lag element (PT2). **Parameters:** - `K, default=1.0` — static gain - `T, default=1.0` — time constant in seconds (must be > 0) - `d, default=1.0` — damping ratio (must be >= 0) **Attributes:** - `input_port_labels` - `output_port_labels` - `K` - `T` - `d` **PT2.__init__**`(K = 1.0, T = 1.0, d = 1.0)` - `K, default=1.0` - `T, default=1.0` - `d, default=1.0` ##### class LeadLag(pathsim.blocks.lti.StateSpace) Lead-Lag compensator. **Parameters:** - `K, default=1.0` — static gain - `T1, default=1.0` — lead (numerator) time constant in seconds - `T2, default=1.0` — lag (denominator) time constant in seconds (must be > 0) **Attributes:** - `input_port_labels` - `output_port_labels` - `K` - `T1` - `T2` **LeadLag.__init__**`(K = 1.0, T1 = 1.0, T2 = 1.0)` - `K, default=1.0` - `T1, default=1.0` - `T2, default=1.0` ##### class PID(pathsim.blocks.lti.StateSpace) Proportional-Integral-Differentiation (PID) controller. **Parameters:** - `Kp, default=0` — proportional controller coefficient - `Ki, default=0` — integral controller coefficient - `Kd, default=0` — differentiator controller coefficient - `f_max, default=100` — highest expected signal frequency **Attributes:** - `input_port_labels` - `output_port_labels` - `Kp` - `Ki` - `Kd` - `f_max` **PID.__init__**`(Kp = 0, Ki = 0, Kd = 0, f_max = 100)` - `Kp, default=0` - `Ki, default=0` - `Kd, default=0` - `f_max, default=100` ##### class AntiWindupPID(pathsim.blocks.ctrl.PID) Proportional-Integral-Differentiation (PID) controller with anti-windup mechanism (back-calculation). **Parameters:** - `Kp, default=0` — proportional controller coefficient - `Ki, default=0` — integral controller coefficient - `Kd, default=0` — differentiator controller coefficient - `f_max, default=100` — highest expected signal frequency - `Ks, default=10` — feedback term for back calculation for anti-windup control of integrator - `limits, default=[-10, 10]` — lower and upper limit for PID output that triggers anti-windup of integrator **Attributes:** - `Ks` - `limits` - `op_dyn` **AntiWindupPID.__init__**`(Kp = 0, Ki = 0, Kd = 0, f_max = 100, Ks = 10, limits = [-10, 10])` - `Kp, default=0` - `Ki, default=0` - `Kd, default=0` - `f_max, default=100` - `Ks, default=10` - `limits, default=[-10, 10]` ##### class RateLimiter(pathsim.blocks.dynsys.DynamicalSystem) Rate limiter block that limits the rate of change of a signal. **Parameters:** - `rate, default=1.0` — maximum rate of change (positive value) - `f_max, default=100` — tracking bandwidth parameter **Attributes:** - `input_port_labels` - `output_port_labels` - `rate` - `f_max` **RateLimiter.__init__**`(rate = 1.0, f_max = 100)` - `rate, default=1.0` - `f_max, default=100` ##### class Backlash(pathsim.blocks.dynsys.DynamicalSystem) Backlash (mechanical play) element. **Parameters:** - `width, default=1.0` — total backlash width (play) - `f_max, default=100` — tracking bandwidth parameter when engaged **Attributes:** - `input_port_labels` - `output_port_labels` - `width` - `f_max` **Backlash.__init__**`(width = 1.0, f_max = 100)` - `width, default=1.0` - `f_max, default=100` ##### class Deadband(pathsim.blocks._block.Block) Deadband (dead zone) element. **Parameters:** - `lower, default=-1.0` — lower bound of the dead zone - `upper, default=1.0` — upper bound of the dead zone **Attributes:** - `input_port_labels` - `output_port_labels` - `lower` - `upper` - `op_alg` **Deadband.__init__**`(lower = -1.0, upper = 1.0)` - `lower, default=-1.0` - `upper, default=1.0` #### pathsim.blocks.delay ##### class Delay(pathsim.blocks._block.Block) Delays the input signal by a time constant 'tau' in seconds. **Parameters:** - `tau, default=0.001` — delay time constant in seconds - `sampling_period, default=None` — sampling period for discrete mode, default is continuous mode **Attributes:** - `tau` - `sampling_period` - `events` **Delay.__init__**`(tau = 0.001, sampling_period = None)` - `tau, default=0.001` - `sampling_period, default=None` **Delay.reset**`()` **Delay.to_checkpoint**`(prefix, recordings = False)` : Serialize Delay state including buffer data. - `prefix` - `recordings, default=False` **Delay.load_checkpoint**`(prefix, json_data, npz)` : Restore Delay state including buffer data. - `prefix` - `json_data` - `npz` **Delay.update**`(t)` : Evaluation of the buffer at different times - `t` — evaluation time **Delay.sample**`(t, dt)` : Sample input values and time of sampling - `t` — evaluation time for sampling - `dt` — integration timestep #### pathsim.blocks.differentiator ##### class Differentiator(pathsim.blocks._block.Block) Differentiates the input signal. **Parameters:** - `f_max, default=100.0` — highest expected signal frequency **Attributes:** - `f_max` - `initial_value` - `op_dyn` - `op_alg` **Differentiator.__init__**`(f_max = 100.0)` - `f_max, default=100.0` **Differentiator.update**`(t)` : update system equation fixed point loop, - `t` — evaluation time **Differentiator.solve**`(t, dt)` : advance solution of implicit update equation - `t` — evaluation time - `dt` — integration timestep **Differentiator.step**`(t, dt)` : compute update step with integration engine - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.divider ##### class Divider(pathsim.blocks._block.Block) Multiplies and divides input signals (MISO). **Parameters:** - `operations, default='*/'` — String of ``*`` and ``/`` characters indicating which inputs are multiplied (``*``) or divided (``/``). Inputs beyond the length of the string default to ``*``. Defaults to ``'*/'`` (divide second input by first). - `zero_div, default='warn'` — Behaviour when a denominator input is zero. One of: **Attributes:** - `input_port_labels` - `output_port_labels` - `zero_div` - `operations` - `op_alg` **Divider.__init__**`(operations = '*/', zero_div = 'warn')` - `operations, default='*/'` - `zero_div, default='warn'` **Divider.update**`(t)` : Update system equation. - `t` — Evaluation time. #### pathsim.blocks.dynsys ##### class DynamicalSystem(pathsim.blocks._block.Block) This block implements a nonlinear dynamical system / nonlinear state space model. **Parameters:** - `func_dyn, default=lambda x, u, t: -x` — right hand side function of ode-part of the system - `func_alg, default=lambda x, u, t: x` — output function of the system - `initial_value, default=0.0` — initial state / initial condition - `jac_dyn, default=None` — optional jacobian of `func_dyn` to improve convergence for implicit ode solvers **Attributes:** - `func_dyn` - `func_alg` - `jac_dyn` - `initial_value` - `op_dyn` - `op_alg` **DynamicalSystem.__init__**`(func_dyn = lambda x, u, t: -x, func_alg = lambda x, u, t: x, initial_value = 0.0, jac_dyn = None)` - `func_dyn, default=lambda x, u, t: -x` - `func_alg, default=lambda x, u, t: x` - `initial_value, default=0.0` - `jac_dyn, default=None` **DynamicalSystem.update**`(t)` : update system equation for fixed point loop, by evaluating the - `t` — evaluation time **DynamicalSystem.solve**`(t, dt)` : advance solution of implicit update equation of the solver - `t` — evaluation time - `dt` — integration timestep **DynamicalSystem.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.filters ##### class ButterworthLowpassFilter(pathsim.blocks.lti.StateSpace) Direct implementation of a low pass butterworth filter block. **Parameters:** - `Fc, default=100` — corner frequency of the filter in [Hz] - `n, default=2` — filter order **Attributes:** - `input_port_labels` - `output_port_labels` - `Fc` - `n` **ButterworthLowpassFilter.__init__**`(Fc = 100, n = 2)` - `Fc, default=100` - `n, default=2` ##### class ButterworthHighpassFilter(pathsim.blocks.lti.StateSpace) Direct implementation of a high pass butterworth filter block. **Parameters:** - `Fc, default=100` — corner frequency of the filter in [Hz] - `n, default=2` — filter order **Attributes:** - `input_port_labels` - `output_port_labels` - `Fc` - `n` **ButterworthHighpassFilter.__init__**`(Fc = 100, n = 2)` - `Fc, default=100` - `n, default=2` ##### class ButterworthBandpassFilter(pathsim.blocks.lti.StateSpace) Direct implementation of a bandpass butterworth filter block. **Parameters:** - `Fc, default=[50, 100]` — corner frequencies (left, right) of the filter in [Hz] - `n, default=2` — filter order **Attributes:** - `input_port_labels` - `output_port_labels` - `Fc` - `n` **ButterworthBandpassFilter.__init__**`(Fc = [50, 100], n = 2)` - `Fc, default=[50, 100]` - `n, default=2` ##### class ButterworthBandstopFilter(pathsim.blocks.lti.StateSpace) Direct implementation of a bandstop butterworth filter block. **Parameters:** - `Fc, default=[50, 100]` — corner frequencies (left, right) of the filter in [Hz] - `n, default=2` — filter order **Attributes:** - `input_port_labels` - `output_port_labels` - `Fc` - `n` **ButterworthBandstopFilter.__init__**`(Fc = [50, 100], n = 2)` - `Fc, default=[50, 100]` - `n, default=2` ##### class AllpassFilter(pathsim.blocks.lti.StateSpace) Direct implementation of a first order allpass filter, or a cascade **Parameters:** - `fs, default=100` — frequency for 90 deg phase shift of 1st order allpass - `n, default=1` — number of cascades **Attributes:** - `input_port_labels` - `output_port_labels` - `fs` - `n` **AllpassFilter.__init__**`(fs = 100, n = 1)` - `fs, default=100` - `n, default=1` #### pathsim.blocks.fir ##### class FIR(pathsim.blocks._block.Block) Models a discrete-time Finite-Impulse-Response (FIR) filter. **Parameters:** - `coeffs, default=[1.0]` — List or numpy array of FIR filter coefficients [b0, b1, ..., bN]. The number of coefficients determines the filter's order and memory. - `T, default=1` — Sampling period (time between input samples and output updates). Default is 1. - `tau, default=0` — Initial delay before the first sample is processed. Default is 0. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` - `T` - `tau` - `events` **FIR.__init__**`(coeffs = [1.0], T = 1, tau = 0)` - `coeffs, default=[1.0]` - `T, default=1` - `tau, default=0` **FIR.reset**`()` : Resets the filter state (buffer) and output. **FIR.to_checkpoint**`(prefix, recordings = False)` : Serialize FIR state including input buffer. - `prefix` - `recordings, default=False` **FIR.load_checkpoint**`(prefix, json_data, npz)` : Restore FIR state including input buffer. - `prefix` - `json_data` - `npz` #### pathsim.blocks.fmu ##### class CoSimulationFMU(pathsim.blocks._block.Block) Co-Simulation FMU block using FMPy with support for FMI 2.0 and FMI 3.0. **Parameters:** - `fmu_path` — path to the FMU file (.fmu) - `instance_name, default='fmu_instance'` — name for the FMU instance (default: 'fmu_instance') - `start_values, default=None` — dictionary of variable names and their initial values - `dt, default=None` — communication step size for co-simulation. If None, uses the FMU's default experiment step size if available. **Attributes:** - `start_values` - `fmu_wrapper` - `dt` - `events` **CoSimulationFMU.__init__**`(fmu_path, instance_name = 'fmu_instance', start_values = None, dt = None)` - `fmu_path` - `instance_name, default='fmu_instance'` - `start_values, default=None` - `dt, default=None` **CoSimulationFMU.reset**`()` : Reset the FMU instance. ##### class ModelExchangeFMU(pathsim.blocks.dynsys.DynamicalSystem) Model Exchange FMU block using FMPy with support for FMI 2.0 and FMI 3.0. **Parameters:** - `fmu_path` — path to the FMU file (.fmu) - `instance_name, default='fmu_instance'` — name for the FMU instance (default: 'fmu_instance') - `start_values, default=None` — dictionary of variable names and their initial values - `tolerance, default=1e-10` — tolerance for event detection (default: 1e-10) - `verbose, default=False` — enable verbose output (default: False) **Attributes:** - `tolerance` - `verbose` - `start_values` - `fmu_wrapper` - `time_event` **ModelExchangeFMU.__init__**`(fmu_path, instance_name = 'fmu_instance', start_values = None, tolerance = 1e-10, verbose = False)` - `fmu_path` - `instance_name, default='fmu_instance'` - `start_values, default=None` - `tolerance, default=1e-10` - `verbose, default=False` **ModelExchangeFMU.sample**`(t, dt)` : Sample block after successful timestep and handle FMU step completion events. - `t` - `dt` **ModelExchangeFMU.reset**`()` : Reset the FMU instance. #### pathsim.blocks.function ##### class Function(pathsim.blocks._block.Block) Arbitrary MIMO function block, defined by a function or `lambda` expression. **Parameters:** - `func, default=lambda x: x` — MIMO function that defines algebraic block IO behaviour, signature `func(*tuple)` **Attributes:** - `func` - `op_alg` **Function.__init__**`(func = lambda x: x)` - `func, default=lambda x: x` **Function.update**`(t)` : Evaluate function block as part of algebraic component - `t` — evaluation time ##### class DynamicalFunction(pathsim.blocks._block.Block) Arbitrary MIMO time and input dependent function block. **Parameters:** - `func, default=lambda u, t: u` — function that defines algebraic block IO behaviour with time dependency, signature `func(u, t)` where `u` is `numpy.ndarray` and `t` is `float` **Attributes:** - `func` - `op_alg` **DynamicalFunction.__init__**`(func = lambda u, t: u)` - `func, default=lambda u, t: u` **DynamicalFunction.update**`(t)` : Evaluate function with time dependency as part of algebraic - `t` — evaluation time #### pathsim.blocks.integrator ##### class Integrator(pathsim.blocks._block.Block) Integrates the input signal. **Parameters:** - `initial_value, default=0.0` — initial value of integrator **Attributes:** - `initial_value` **Integrator.__init__**`(initial_value = 0.0)` - `initial_value, default=0.0` **Integrator.update**`(t)` : update system equation fixed point loop - `t` — evaluation time **Integrator.solve**`(t, dt)` : advance solution of implicit update equation of the solver - `t` — evaluation time - `dt` — integration timestep **Integrator.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.kalman ##### class KalmanFilter(pathsim.blocks._block.Block) Discrete-time Kalman filter for state estimation. **Parameters:** - `F` — State transition matrix (n x n). Describes how the state evolves from one time step to the next. - `H` — Measurement matrix (m x n). Maps the state space to the measurement space. - `Q` — Process noise covariance matrix (n x n). Represents uncertainty in the system model. - `R` — Measurement noise covariance matrix (m x m). Represents uncertainty in the measurements. - `B, default=None` — Control input matrix (n x p). Maps control inputs to state changes. Default is None (no control input). - `x0, default=None` — Initial state estimate (n,). Default is zero vector. - `P0, default=None` — Initial error covariance matrix (n x n). Default is identity matrix. - `dt, default=None` **Attributes:** - `F` - `H` - `Q` - `R` - `B` - `dt` - `x` - `P` - `inputs` - `outputs` - `events` **KalmanFilter.__init__**`(F, H, Q, R, B = None, x0 = None, P0 = None, dt = None)` - `F` - `H` - `Q` - `R` - `B, default=None` - `x0, default=None` - `P0, default=None` - `dt, default=None` **KalmanFilter.to_checkpoint**`(prefix, recordings = False)` : Serialize Kalman filter state estimate and covariance. - `prefix` - `recordings, default=False` **KalmanFilter.load_checkpoint**`(prefix, json_data, npz)` : Restore Kalman filter state estimate and covariance. - `prefix` - `json_data` - `npz` **KalmanFilter.sample**`(t, dt)` : Sample after successful timestep. - `t` — evaluation time for sampling - `dt` — integration timestep #### pathsim.blocks.logic ##### class Logic(pathsim.blocks._block.Block) Base logic block. **Logic.update**`(t)` : update algebraic component of system equation - `t` — evaluation time ##### class GreaterThan(pathsim.blocks.logic.Logic) Greater-than comparison block. **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **GreaterThan.__init__**`()` ##### class LessThan(pathsim.blocks.logic.Logic) Less-than comparison block. **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **LessThan.__init__**`()` ##### class Equal(pathsim.blocks.logic.Logic) Equality comparison block. **Parameters:** - `tolerance, default=1e-12` — comparison tolerance for floating point equality **Attributes:** - `input_port_labels` - `output_port_labels` - `tolerance` - `op_alg` **Equal.__init__**`(tolerance = 1e-12)` - `tolerance, default=1e-12` ##### class LogicAnd(pathsim.blocks.logic.Logic) Logical AND block. **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **LogicAnd.__init__**`()` ##### class LogicOr(pathsim.blocks.logic.Logic) Logical OR block. **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **LogicOr.__init__**`()` ##### class LogicNot(pathsim.blocks.logic.Logic) Logical NOT block. **Attributes:** - `op_alg` **LogicNot.__init__**`()` #### pathsim.blocks.lti ##### class StateSpace(pathsim.blocks._block.Block) Linear time invariant (LTI) multi input multi output (MIMO) state space model. **Parameters:** - `A, default=-1.0` - `B, default=1.0` - `C, default=-1.0` - `D, default=1.0` — real valued state space matrices - `initial_value, default=None` — initial state / initial condition **Attributes:** - `A` - `B` - `C` - `D` - `inputs` - `outputs` - `initial_value` - `op_dyn` - `op_alg` **StateSpace.__init__**`(A = -1.0, B = 1.0, C = -1.0, D = 1.0, initial_value = None)` - `A, default=-1.0` - `B, default=1.0` - `C, default=-1.0` - `D, default=1.0` - `initial_value, default=None` **StateSpace.solve**`(t, dt)` : advance solution of implicit update equation of the solver - `t` — evaluation time - `dt` — integration timestep **StateSpace.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep ##### class TransferFunctionPRC(pathsim.blocks.lti.StateSpace) This block defines a LTI (MIMO for pole residue) transfer function. **Parameters:** - `Poles, default=[]` — transfer function poles - `Residues, default=[]` — transfer function residues - `Const, default=0.0` — constant term of transfer function **TransferFunctionPRC.__init__**`(Poles = [], Residues = [], Const = 0.0)` - `Poles, default=[]` - `Residues, default=[]` - `Const, default=0.0` ##### class TransferFunction(pathsim.blocks.lti.TransferFunctionPRC) Alias for TransferFunctionPRC. ##### class TransferFunctionZPG(pathsim.blocks.lti.StateSpace) This block defines a LTI (SISO) transfer function. **Parameters:** - `Zeros, default=[]` — transfer function zeros - `Poles, default=[-1]` — transfer function poles - `Gain, default=1.0` — gain term of transfer function **Attributes:** - `input_port_labels` - `output_port_labels` **TransferFunctionZPG.__init__**`(Zeros = [], Poles = [-1], Gain = 1.0)` - `Zeros, default=[]` - `Poles, default=[-1]` - `Gain, default=1.0` ##### class TransferFunctionNumDen(pathsim.blocks.lti.StateSpace) This block defines a LTI (SISO) transfer function. **Parameters:** - `Num, default=[1]` — numerator polynomial coefficients - `Den, default=[1, 1]` — denominator polynomial coefficients **Attributes:** - `input_port_labels` - `output_port_labels` **TransferFunctionNumDen.__init__**`(Num = [1], Den = [1, 1])` - `Num, default=[1]` - `Den, default=[1, 1]` #### pathsim.blocks.math ##### class Math(pathsim.blocks._block.Block) Base math block. **Math.update**`(t)` : update algebraic component of system equation - `t` — evaluation time ##### class Sin(pathsim.blocks.math.Math) Sine operator block. **Attributes:** - `op_alg` **Sin.__init__**`()` ##### class Cos(pathsim.blocks.math.Math) Cosine operator block. **Attributes:** - `op_alg` **Cos.__init__**`()` ##### class Sqrt(pathsim.blocks.math.Math) Square root operator block. **Attributes:** - `op_alg` **Sqrt.__init__**`()` ##### class Abs(pathsim.blocks.math.Math) Absolute value operator block. **Attributes:** - `op_alg` **Abs.__init__**`()` ##### class Pow(pathsim.blocks.math.Math) Raise to power operator block. **Parameters:** - `exponent, default=2` — exponent to raise the input to the power of Attributes ---------- **Attributes:** - `exponent` - `op_alg` **Pow.__init__**`(exponent = 2)` - `exponent, default=2` ##### class PowProd(pathsim.blocks.math.Math) Power-Product operator block. **Parameters:** - `exponents, default=2` — exponent(s) to raise the inputs to the power of. If scalar, applies same exponent to all inputs. Attributes ---------- **Attributes:** - `exponents` - `op_alg` **PowProd.__init__**`(exponents = 2)` - `exponents, default=2` ##### class Exp(pathsim.blocks.math.Math) Exponential operator block. **Attributes:** - `op_alg` **Exp.__init__**`()` ##### class Log(pathsim.blocks.math.Math) Natural logarithm operator block. **Attributes:** - `op_alg` **Log.__init__**`()` ##### class Log10(pathsim.blocks.math.Math) Base-10 logarithm operator block. **Attributes:** - `op_alg` **Log10.__init__**`()` ##### class Tan(pathsim.blocks.math.Math) Tangent operator block. **Attributes:** - `op_alg` **Tan.__init__**`()` ##### class Sinh(pathsim.blocks.math.Math) Hyperbolic sine operator block. **Attributes:** - `op_alg` **Sinh.__init__**`()` ##### class Cosh(pathsim.blocks.math.Math) Hyperbolic cosine operator block. **Attributes:** - `op_alg` **Cosh.__init__**`()` ##### class Tanh(pathsim.blocks.math.Math) Hyperbolic tangent operator block. **Attributes:** - `op_alg` **Tanh.__init__**`()` ##### class Atan(pathsim.blocks.math.Math) Arctangent operator block. **Attributes:** - `op_alg` **Atan.__init__**`()` ##### class Norm(pathsim.blocks.math.Math) Vector norm operator block. **Attributes:** - `op_alg` **Norm.__init__**`()` ##### class Mod(pathsim.blocks.math.Math) Modulo operator block. **Parameters:** - `modulus, default=1.0` — modulus value Attributes ---------- **Attributes:** - `modulus` - `op_alg` **Mod.__init__**`(modulus = 1.0)` - `modulus, default=1.0` ##### class Clip(pathsim.blocks.math.Math) Clipping/saturation operator block. **Parameters:** - `min_val, default=-1.0` — minimum clipping value - `max_val, default=1.0` — maximum clipping value Attributes ---------- **Attributes:** - `min_val` - `max_val` - `op_alg` **Clip.__init__**`(min_val = -1.0, max_val = 1.0)` - `min_val, default=-1.0` - `max_val, default=1.0` ##### class Matrix(pathsim.blocks.math.Math) Linear matrix operation (matrix-vector product). **Parameters:** - `A, default=np.eye(1)` — matrix, 2d array with dim=2 Attributes ---------- **Attributes:** - `inputs` - `outputs` - `A` - `op_alg` **Matrix.__init__**`(A = np.eye(1))` - `A, default=np.eye(1)` ##### class Atan2(pathsim.blocks._block.Block) Two-argument arctangent block. **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **Atan2.__init__**`()` **Atan2.update**`(t)` : update algebraic component of system equation - `t` — evaluation time ##### class Rescale(pathsim.blocks.math.Math) Linear rescaling / mapping block. **Parameters:** - `i0, default=0.0` — input range lower bound - `i1, default=1.0` — input range upper bound - `o0, default=0.0` — output range lower bound - `o1, default=1.0` — output range upper bound - `saturate, default=False` — if True, clamp output to [min(o0,o1), max(o0,o1)] **Attributes:** - `i0` - `i1` - `o0` - `o1` - `saturate` - `op_alg` **Rescale.__init__**`(i0 = 0.0, i1 = 1.0, o0 = 0.0, o1 = 1.0, saturate = False)` - `i0, default=0.0` - `i1, default=1.0` - `o0, default=0.0` - `o1, default=1.0` - `saturate, default=False` ##### class Alias(pathsim.blocks.math.Math) Signal alias / pass-through block. **Attributes:** - `op_alg` **Alias.__init__**`()` #### pathsim.blocks.multiplier ##### class Multiplier(pathsim.blocks._block.Block) Multiplies all signals from all input ports (MISO). **Attributes:** - `input_port_labels` - `output_port_labels` - `op_alg` **Multiplier.__init__**`()` **Multiplier.update**`(t)` : update system equation - `t` — evaluation time #### pathsim.blocks.noise ##### class WhiteNoise(pathsim.blocks._block.Block) White noise source with Gaussian distribution. **Parameters:** - `standard_deviation, default=1.0` — output standard deviation for constant-amplitude mode (default: 1.0) - `spectral_density, default=None` — power spectral density S₀ in [signal²/Hz] - `sampling_period, default=None` — time between samples, if None samples every timestep - `seed, default=None` — random seed for reproducibility **Attributes:** - `input_port_labels` - `output_port_labels` - `standard_deviation` - `spectral_density` - `sampling_period` - `events` **WhiteNoise.__init__**`(standard_deviation = 1.0, spectral_density = None, sampling_period = None, seed = None)` - `standard_deviation, default=1.0` - `spectral_density, default=None` - `sampling_period, default=None` - `seed, default=None` **WhiteNoise.sample**`(t, dt)` : Generate new noise sample after successful timestep. - `t` — evaluation time - `dt` — integration timestep **WhiteNoise.update**`(t)` - `t` **WhiteNoise.to_checkpoint**`(prefix, recordings = False)` : Serialize WhiteNoise state including current sample. - `prefix` - `recordings, default=False` **WhiteNoise.load_checkpoint**`(prefix, json_data, npz)` : Restore WhiteNoise state including current sample. - `prefix` - `json_data` - `npz` ##### class PinkNoise(pathsim.blocks._block.Block) Pink noise (1/f noise) source using the Voss-McCartney algorithm. **Parameters:** - `standard_deviation, default=1.0` — approximate output standard deviation (default: 1.0) - `spectral_density, default=None` — power spectral density, output scaled as √(S₀/(N·dt)) - `num_octaves, default=16` — number of frequency bands in algorithm (default: 16) - `sampling_period, default=None` — time between samples, if None samples every timestep - `seed, default=None` — random seed for reproducibility **Attributes:** - `input_port_labels` - `output_port_labels` - `standard_deviation` - `spectral_density` - `num_octaves` - `sampling_period` - `n_samples` - `octave_values` - `events` **PinkNoise.__init__**`(standard_deviation = 1.0, spectral_density = None, num_octaves = 16, sampling_period = None, seed = None)` - `standard_deviation, default=1.0` - `spectral_density, default=None` - `num_octaves, default=16` - `sampling_period, default=None` - `seed, default=None` **PinkNoise.reset**`()` : Reset the noise generator state. **PinkNoise.sample**`(t, dt)` : Generate new noise sample after successful timestep. - `t` — evaluation time - `dt` — integration timestep **PinkNoise.update**`(t)` - `t` **PinkNoise.to_checkpoint**`(prefix, recordings = False)` : Serialize PinkNoise state including algorithm state. - `prefix` - `recordings, default=False` **PinkNoise.load_checkpoint**`(prefix, json_data, npz)` : Restore PinkNoise state including algorithm state. - `prefix` - `json_data` - `npz` #### pathsim.blocks.ode ##### class ODE(pathsim.blocks._block.Block) Ordinary differential equation (ODE) defined by its right hand side function. **Parameters:** - `func, default=lambda x, u, t: -x` — right hand side function of ODE - `initial_value, default=0.0` — initial state / initial condition - `jac, default=None` — jacobian of 'func' or 'None' **Attributes:** - `func` - `initial_value` - `jac` - `op_dyn` **ODE.__init__**`(func = lambda x, u, t: -x, initial_value = 0.0, jac = None)` - `func, default=lambda x, u, t: -x` - `initial_value, default=0.0` - `jac, default=None` **ODE.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time **ODE.solve**`(t, dt)` : advance solution of implicit update equation of the solver - `t` — evaluation time - `dt` — integration timestep **ODE.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.relay ##### class Relay(pathsim.blocks._block.Block) Relay block with hysteresis (Schmitt trigger). **Parameters:** - `threshold_up, default=1.0` — threshold for transitioning to upper relay state `value_up` (default: 1.0) - `threshold_down, default=0.0` — threshold for transitioning to lower relay state `value_down` (default: 0.0) - `value_up, default=1.0` — value for upper relay state (default: 1.0) - `value_down, default=0.0` — value for lower relay state (default: 0.0) **Attributes:** - `input_port_labels` - `output_port_labels` - `threshold_up` - `threshold_down` - `value_up` - `value_down` - `events` **Relay.__init__**`(threshold_up = 1.0, threshold_down = 0.0, value_up = 1.0, value_down = 0.0)` - `threshold_up, default=1.0` - `threshold_down, default=0.0` - `value_up, default=1.0` - `value_down, default=0.0` **Relay.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time #### pathsim.blocks.rf ##### class RFNetwork(pathsim.blocks.lti.StateSpace) N-port RF network linear time invariant (LTI) multi input multi output (MIMO) state-space model. **Parameters:** - `ntwk (NetworkType | str | Path)` — scikit-rf [skrf]_ RF Network object, or file to load information from. Supported formats are touchstone file V1 (.s?p) or V2 (.ts). - `auto_fit (bool), default=True` - `kwargs, default={}` **Attributes:** - `network` - `vf` **RFNetwork.__init__**`(ntwk: NetworkType | str | Path, auto_fit: bool = True, kwargs = {})` - `ntwk` - `auto_fit, default=True` - `kwargs, default={}` **RFNetwork.s**`(freqs: np.ndarray)` : S-matrix of the vector fitted N-port model calculated from its state-space representation. - `freqs` — Frequencies (in Hz) at which to calculate the S-matrices. #### pathsim.blocks.rng ##### class RandomNumberGenerator(pathsim.blocks._block.Block) Generates a random output value using `numpy.random.rand`. **Parameters:** - `sampling_period, default=None` — time between random samples **Attributes:** - `input_port_labels` - `output_port_labels` - `sampling_period` - `Evt` - `events` **RandomNumberGenerator.__init__**`(sampling_period = None)` - `sampling_period, default=None` **RandomNumberGenerator.update**`(t)` : Setting output with random sample in case - `t` — evaluation time **RandomNumberGenerator.sample**`(t, dt)` : Generating a new random sample at each timestep - `t` — evaluation time - `dt` — integration timestep **RandomNumberGenerator.to_checkpoint**`(prefix, recordings = False)` : Serialize RNG state including current sample. - `prefix` - `recordings, default=False` **RandomNumberGenerator.load_checkpoint**`(prefix, json_data, npz)` : Restore RNG state including current sample. - `prefix` - `json_data` - `npz` ##### class RNG(pathsim.blocks.rng.RandomNumberGenerator) Alias for RandomNumberGenerator. #### pathsim.blocks.samplehold ##### class SampleHold(pathsim.blocks._block.Block) Samples the inputs periodically and produces them at the output. **Parameters:** - `T, default=1` — sampling period - `tau, default=0` — delay Attributes ---------- **Attributes:** - `T` - `tau` - `events` **SampleHold.__init__**`(T = 1, tau = 0)` - `T, default=1` - `tau, default=0` #### pathsim.blocks.scope ##### class Scope(pathsim.blocks._block.Block) Block for recording time domain data with variable sampling period. **Parameters:** - `sampling_period, default=None` — time between samples, default is every timestep - `t_wait, default=0.0` — wait time before starting recording, optional - `labels, default=None` — labels for the scope traces, and for the csv, optional **Attributes:** - `input_port_labels` - `output_port_labels` - `t_wait` - `sampling_period` - `labels` - `recording_time` - `recording_data` - `events` **Scope.__init__**`(sampling_period = None, t_wait = 0.0, labels = None)` - `sampling_period, default=None` - `t_wait, default=0.0` - `labels, default=None` **Scope.reset**`()` **Scope.read**`(incremental = False)` : Return the recorded time domain data and the corresponding - `incremental, default=False` — read the data incrementally, only return new data that has accumulated after the last incremental read call **Scope.collect**`()` : Yield (category, id, data) tuples for recording blocks to simplify **Scope.sample**`(t, dt)` : Sample the data from all inputs. Skips duplicate timestamps to maintain - `t` — evaluation time for sampling - `dt` **Scope.plot**`(args = (), kwargs = {})` : Directly create a plot of the recorded data for quick visualization and debugging. - `args, default=()` — args for ax.plot - `kwargs, default={}` — kwargs for ax.plot **Scope.plot2D**`(args = (), axes = (0, 1), kwargs = {})` : Directly create a 2D plot of the recorded data for quick visualization and debugging. - `args, default=()` — args for ax.plot - `axes, default=(0, 1)` — axes / ports to select for 2d plot - `kwargs, default={}` — kwargs for ax.plot **Scope.plot3D**`(args = (), axes = (0, 1, 2), kwargs = {})` : Directly create a 3D plot of the recorded data for quick visualization. - `args, default=()` — args for ax.plot - `axes, default=(0, 1, 2)` — indices of the three data channels (ports) to plot (default: (0, 1, 2)). - `kwargs, default={}` — kwargs for ax.plot **Scope.save**`(path = 'scope.csv')` : Save the recording of the scope to a csv file. - `path, default='scope.csv'` — path where to save the recording as a csv file **Scope.to_checkpoint**`(prefix, recordings = False)` : Serialize Scope state including optional recording data. - `prefix` - `recordings, default=False` **Scope.load_checkpoint**`(prefix, json_data, npz)` : Restore Scope state including optional recording data. - `prefix` - `json_data` - `npz` **Scope.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time ##### class RealtimeScope(pathsim.blocks.scope.Scope) An extension of the 'Scope' block that initializes a realtime plotter. **Parameters:** - `sampling_period, default=None` — time between samples, default is every timestep - `t_wait, default=0.0` — wait time before starting recording - `labels, default=[]` — labels for the scope traces, and for the csv - `max_samples, default=None` — number of samples for realtime display, all per default **Attributes:** - `plotter` **RealtimeScope.__init__**`(sampling_period = None, t_wait = 0.0, labels = [], max_samples = None)` - `sampling_period, default=None` - `t_wait, default=0.0` - `labels, default=[]` - `max_samples, default=None` **RealtimeScope.sample**`(t, dt)` : Sample the data from all inputs, and overwrites existing timepoints, - `t` — evaluation time for sampling - `dt` #### pathsim.blocks.sources ##### class Constant(pathsim.blocks._block.Block) Produces a constant output signal (SISO). **Parameters:** - `value, default=1` — constant defining block output **Attributes:** - `input_port_labels` - `output_port_labels` - `value` **Constant.__init__**`(value = 1)` - `value, default=1` **Constant.update**`(t)` : update system equation fixed point loop - `t` — evaluation time ##### class Source(pathsim.blocks._block.Block) Source that produces an arbitrary time dependent output defined by `func` (callable). **Parameters:** - `func, default=lambda t: 1` — function defining time dependent block output **Attributes:** - `input_port_labels` - `output_port_labels` - `func` **Source.__init__**`(func = lambda t: 1)` - `func, default=lambda t: 1` **Source.update**`(t)` : update system equation fixed point loop - `t` — evaluation time ##### class TriangleWaveSource(pathsim.blocks.sources.Source) Source block that generates an analog triangle wave **Parameters:** - `frequency, default=1` — frequency of the triangle wave - `amplitude, default=1` — amplitude of the triangle wave - `phase, default=0` — phase of the triangle wave **Attributes:** - `amplitude` - `frequency` - `phase` **TriangleWaveSource.__init__**`(frequency = 1, amplitude = 1, phase = 0)` - `frequency, default=1` - `amplitude, default=1` - `phase, default=0` ##### class SinusoidalSource(pathsim.blocks.sources.Source) Source block that generates a sinusoid wave **Parameters:** - `frequency, default=1` — frequency of the sinusoid - `amplitude, default=1` — amplitude of the sinusoid - `phase, default=0` — phase of the sinusoid **Attributes:** - `amplitude` - `frequency` - `phase` **SinusoidalSource.__init__**`(frequency = 1, amplitude = 1, phase = 0)` - `frequency, default=1` - `amplitude, default=1` - `phase, default=0` ##### class GaussianPulseSource(pathsim.blocks.sources.Source) Source block that generates a gaussian pulse **Parameters:** - `amplitude, default=1` — amplitude of the gaussian pulse - `f_max, default=1000.0` — maximum frequency component of the gaussian pulse (steepness) - `tau, default=0.0` — time delay of the gaussian pulse **Attributes:** - `outputs` - `amplitude` - `f_max` - `tau` **GaussianPulseSource.__init__**`(amplitude = 1, f_max = 1000.0, tau = 0.0)` - `amplitude, default=1` - `f_max, default=1000.0` - `tau, default=0.0` ##### class SinusoidalPhaseNoiseSource(pathsim.blocks._block.Block) Sinusoidal source with cumulative and white phase noise. **Parameters:** - `frequency, default=1` — frequency of the sinusoid - `amplitude, default=1` — amplitude of the sinusoid - `phase, default=0` — initial phase of the sinusoid (radians) - `sig_cum, default=0` — weight for cumulative phase noise contribution - `sig_white, default=0` — weight for white phase noise contribution - `sampling_period, default=0.1` — time between phase noise samples. If None, noise is sampled every timestep (default is 0.1) **Attributes:** - `input_port_labels` - `output_port_labels` - `amplitude` - `frequency` - `phase` - `sampling_period` - `omega` - `sig_cum` - `sig_white` - `noise_1` - `noise_2` - `initial_value` - `events` **SinusoidalPhaseNoiseSource.__init__**`(frequency = 1, amplitude = 1, phase = 0, sig_cum = 0, sig_white = 0, sampling_period = 0.1)` - `frequency, default=1` - `amplitude, default=1` - `phase, default=0` - `sig_cum, default=0` - `sig_white, default=0` - `sampling_period, default=0.1` **SinusoidalPhaseNoiseSource.reset**`()` : Reset block state including noise samples. **SinusoidalPhaseNoiseSource.update**`(t)` : Update system equation for fixed point loop, evaluating the - `t` — evaluation time **SinusoidalPhaseNoiseSource.sample**`(t, dt)` : Sample from a normal distribution after successful timestep. - `t` — evaluation time - `dt` — integration timestep **SinusoidalPhaseNoiseSource.solve**`(t, dt)` : Advance solution of implicit update equation for cumulative noise integration. - `t` — evaluation time - `dt` — integration timestep Returns ------- float error estimate (always 0.0 for noise source) **SinusoidalPhaseNoiseSource.step**`(t, dt)` : Compute update step with integration engine for cumulative noise. - `t` — evaluation time - `dt` — integration timestep Returns ------- tuple (accepted, error, scale_factor) - always (True, 0.0, None) for noise ##### class ChirpPhaseNoiseSource(pathsim.blocks._block.Block) Chirp source, sinusoid with frequency ramp up and ramp down, plus phase noise. **Parameters:** - `amplitude, default=1` — amplitude of the chirp signal - `f0, default=1` — start frequency of the chirp signal - `BW, default=1` — bandwidth of the frequency ramp of the chirp signal - `T, default=1` — period of the frequency ramp of the chirp signal - `phase, default=0` — phase of sinusoid (initial, radians) - `sig_cum, default=0` — weight for cumulative phase noise contribution - `sig_white, default=0` — weight for white phase noise contribution - `sampling_period, default=0.1` — time between phase noise samples. If None, noise is sampled every timestep (default is 0.1) **Attributes:** - `input_port_labels` - `output_port_labels` - `amplitude` - `phase` - `f0` - `BW` - `T` - `sig_cum` - `sig_white` - `sampling_period` - `noise_1` - `noise_2` - `initial_value` - `events` **ChirpPhaseNoiseSource.__init__**`(amplitude = 1, f0 = 1, BW = 1, T = 1, phase = 0, sig_cum = 0, sig_white = 0, sampling_period = 0.1)` - `amplitude, default=1` - `f0, default=1` - `BW, default=1` - `T, default=1` - `phase, default=0` - `sig_cum, default=0` - `sig_white, default=0` - `sampling_period, default=0.1` **ChirpPhaseNoiseSource.reset**`()` : Reset block state including noise samples. **ChirpPhaseNoiseSource.sample**`(t, dt)` : Sample from a normal distribution after successful timestep - `t` — evaluation time - `dt` — integration timestep **ChirpPhaseNoiseSource.update**`(t)` : Update the block output, assemble phase and evaluate the sinusoid. - `t` — evaluation time **ChirpPhaseNoiseSource.solve**`(t, dt)` : Advance implicit solver of implicit integration engine, evaluate - `t` — evaluation time - `dt` — integration timestep Returns ------- float error estimate (always 0.0 for chirp source) **ChirpPhaseNoiseSource.step**`(t, dt)` : Compute update step with integration engine, evaluate the triangle wave - `t` — evaluation time - `dt` — integration timestep Returns ------- tuple (accepted, error, scale_factor) - always (True, 0.0, None) for chirp ##### class ChirpSource(pathsim.blocks.sources.ChirpPhaseNoiseSource) Alias for ChirpPhaseNoiseSource. ##### class PulseSource(pathsim.blocks._block.Block) Generates a periodic pulse waveform with defined rise and fall times. **Parameters:** - `amplitude, default=1.0` — Peak amplitude of the pulse. Default is 1.0. - `T, default=1.0` — Period of the pulse train. Must be positive. Default is 1.0. - `t_rise, default=0.0` — Duration of the rising edge. Default is 0.0. - `t_fall, default=0.0` — Duration of the falling edge. Default is 0.0. - `tau, default=0.0` — Initial delay before the first pulse cycle begins. Default is 0.0. - `duty, default=0.5` — Duty cycle, ratio of the pulse ON duration (plateau time only) to the total period T (must be between 0 and 1). Default is 0.5. The high plateau duration is `T * duty`. **Attributes:** - `input_port_labels` - `output_port_labels` - `amplitude` - `T` - `t_rise` - `t_fall` - `tau` - `duty` - `events` **PulseSource.__init__**`(amplitude = 1.0, T = 1.0, t_rise = 0.0, t_fall = 0.0, tau = 0.0, duty = 0.5)` - `amplitude, default=1.0` - `T, default=1.0` - `t_rise, default=0.0` - `t_fall, default=0.0` - `tau, default=0.0` - `duty, default=0.5` **PulseSource.reset**`(t: float = None)` : Resets the block state. - `t, default=None` — Time to reset the block state at. If None, resets to initial state. **PulseSource.update**`(t)` : Calculate the pulse output value based on the current phase. - `t` — evaluation time ##### class Pulse(pathsim.blocks.sources.PulseSource) Alias for PulseSource. ##### class ClockSource(pathsim.blocks._block.Block) Discrete time clock source block. **Parameters:** - `T, default=1` — period of the clock - `tau, default=0` — clock delay **Attributes:** - `input_port_labels` - `output_port_labels` - `T` - `tau` - `events` **ClockSource.__init__**`(T = 1, tau = 0)` - `T, default=1` - `tau, default=0` ##### class Clock(pathsim.blocks.sources.ClockSource) Alias for ClockSource. ##### class SquareWaveSource(pathsim.blocks._block.Block) Discrete time square wave source. **Parameters:** - `amplitude, default=1` — amplitude of the square wave signal - `frequency, default=1` — frequency of the square wave signal - `phase, default=0` — phase of the square wave signal **Attributes:** - `input_port_labels` - `output_port_labels` - `amplitude` - `frequency` - `phase` - `events` **SquareWaveSource.__init__**`(amplitude = 1, frequency = 1, phase = 0)` - `amplitude, default=1` - `frequency, default=1` - `phase, default=0` ##### class StepSource(pathsim.blocks._block.Block) Discrete time unit step (or multi step) source block. **Parameters:** - `amplitude, default=1` — amplitude of the step signal, or amplitudes / output levels of the multiple steps - `tau, default=0.0` — delay of the step, or delays of the different steps **Attributes:** - `input_port_labels` - `output_port_labels` - `amplitude` - `tau` - `Evt` - `events` **StepSource.__init__**`(amplitude = 1, tau = 0.0)` - `amplitude, default=1` - `tau, default=0.0` ##### class Step(pathsim.blocks.sources.StepSource) Alias for StepSource. #### pathsim.blocks.spectrum ##### class Spectrum(pathsim.blocks._block.Block) Block for fourier spectrum analysis (spectrum analyzer). **Parameters:** - `freq, default=[]` — list of evaluation frequencies for RFT, can be arbitrarily spaced - `t_wait, default=0.0` — wait time before starting RFT - `alpha, default=0.0` — exponential forgetting factor for realtime spectrum - `labels, default=[]` — labels for the inputs **Attributes:** - `input_port_labels` - `output_port_labels` - `t_wait` - `t_sample` - `time` - `alpha` - `labels` - `freq` - `omega` - `initial_value` **Spectrum.__init__**`(freq = [], t_wait = 0.0, alpha = 0.0, labels = [])` - `freq, default=[]` - `t_wait, default=0.0` - `alpha, default=0.0` - `labels, default=[]` **Spectrum.reset**`()` **Spectrum.read**`()` : Read the recorded spectrum **Spectrum.collect**`()` : Yield (category, id, data) tuples for recording blocks to simplify **Spectrum.solve**`(t, dt)` : advance solution of implicit update equation of the solver - `t` — evaluation time - `dt` — integration timestep **Spectrum.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep **Spectrum.to_checkpoint**`(prefix, recordings = False)` : Serialize Spectrum state including integration time. - `prefix` - `recordings, default=False` **Spectrum.load_checkpoint**`(prefix, json_data, npz)` : Restore Spectrum state including integration time. - `prefix` - `json_data` - `npz` **Spectrum.sample**`(t, dt)` : sample time of successfull timestep for waiting period - `t` — sampling time - `dt` — integration timestep **Spectrum.plot**`(args = (), kwargs = {})` : Directly create a plot of the recorded data for visualization. - `args, default=()` — args for ax.plot - `kwargs, default={}` — kwargs for ax.plot **Spectrum.save**`(path = 'spectrum.csv')` : Save the recording of the spectrum to a csv file - `path, default='spectrum.csv'` — path where to save the recording as a csv file **Spectrum.update**`(t)` : update system equation for fixed point loop, - `t` — evaluation time ##### class RealtimeSpectrum(pathsim.blocks.spectrum.Spectrum) An extension of the 'Spectrum' block that also initializes a realtime plotter. **Parameters:** - `freq, default=[]` — list of evaluation frequencies for RFT, can be arbitrarily spaced - `t_wait, default=0.0` — wait time before starting RFT - `alpha, default=0.0` — exponential forgetting factor for realtime spectrum - `labels, default=[]` — labels for the inputs **Attributes:** - `plotter` **RealtimeSpectrum.__init__**`(freq = [], t_wait = 0.0, alpha = 0.0, labels = [])` - `freq, default=[]` - `t_wait, default=0.0` - `alpha, default=0.0` - `labels, default=[]` **RealtimeSpectrum.step**`(t, dt)` : compute timestep update with integration engine - `t` — evaluation time - `dt` — integration timestep #### pathsim.blocks.switch ##### class Switch(pathsim.blocks._block.Block) Switch block that selects between its inputs. **Parameters:** - `switch_state, default=None` — state of the switch **Attributes:** - `input_port_labels` - `output_port_labels` - `switch_state` **Switch.__init__**`(switch_state = None)` - `switch_state, default=None` **Switch.select**`(switch_state = 0)` : This method is unique to the `Switch` block and intended - `switch_state, default=0` — switch state / input port selection **Switch.to_checkpoint**`(prefix, recordings = False)` - `prefix` - `recordings, default=False` **Switch.load_checkpoint**`(prefix, json_data, npz)` - `prefix` - `json_data` - `npz` **Switch.update**`(t)` : Update switch output depending on inputs and switch state. - `t` — evaluation time #### pathsim.blocks.table ##### class LUT(pathsim.blocks.Function) N-dimensional lookup table with linear interpolation functionality. **Parameters:** - `points, default=None` — 2-D array of data point coordinates where n is the number of points and ndim is the dimensionality of the space. Each row represents a single data point in ndim-dimensional space. - `values, default=None` — N-D array of data values at the corresponding points. If 1-D, represents scalar values at each point. If 2-D, each column represents a different output dimension (m output values per input point). **Attributes:** - `points` - `values` - `inter` **LUT.__init__**`(points = None, values = None)` - `points, default=None` - `values, default=None` ##### class LUT1D(pathsim.blocks.Function) One-dimensional lookup table with linear interpolation functionality. **Parameters:** - `points, default=None` — 1-D array of monotonically increasing data point coordinates where n is the number of points. These represent the independent variable values at which the dependent values are known. - `values, default=None` — 1-D or 2-D array of data values at the corresponding points. If 1-D, represents scalar values at each point. If 2-D with shape (n, m), each column represents a different output dimension, allowing the lookup table to return m-dimensional vectors. - `fill_value, default='extrapolate'` — The value to use for points outside the interpolation range. If "extrapolate", the interpolator will use linear extrapolation. Default is "extrapolate". See https://docs.scipy.org/doc/scipy-1.16.1/reference/generated/scipy.interpolate.interp1d.html for more details **Attributes:** - `points` - `values` - `inter` **LUT1D.__init__**`(points = None, values = None, fill_value = 'extrapolate')` - `points, default=None` - `values, default=None` - `fill_value, default='extrapolate'` #### pathsim.blocks.wrapper ##### class Wrapper(pathsim.blocks._block.Block) Wrapper block for discrete implementation and external code integration. **Parameters:** - `func, default=None` — function that defines algebraic block IO behaviour - `T, default=1` — sampling period for the wrapped function - `tau, default=0` — delay time for the start time of the event Attributes ---------- **Attributes:** - `func` - `Evt` - `events` - `tau` — Getter for tau - `T` — Get the sampling period of the block **Wrapper.__init__**`(func = None, T = 1, tau = 0)` - `func, default=None` - `T, default=1` - `tau, default=0` **Wrapper.update**`(t)` : Update system equation for fixed point loop. - `t` — evaluation time **Wrapper.dec**`(cls, T = 1, tau = 0)` : decorator for direct instance construction from func - `T, default=1` — sampling period for calling the `wrapped` function - `tau, default=0` — delay time for the start time of the wrapper sampling #### pathsim.events._event ##### class Event This is the base class of the event handling system. **Parameters:** - `func_evt, default=None` — event function, where zeros are events - `func_act, default=None` — action function for event resolution - `tolerance, default=EVT_TOLERANCE` — tolerance to check if detection is close to actual event **Attributes:** - `func_evt` - `func_act` - `tolerance` **Event.__init__**`(func_evt = None, func_act = None, tolerance = EVT_TOLERANCE)` - `func_evt, default=None` - `func_act, default=None` - `tolerance, default=EVT_TOLERANCE` **Event.on**`()` **Event.off**`()` **Event.reset**`()` : Reset the recorded event times. Resetting the history is not **Event.buffer**`(t)` : Buffer the event function evaluation before the timestep is - `t` — evaluation time for buffering history **Event.estimate**`(t)` : Estimate the time of the next event, based on history or internal schedule. - `t` — evaluation time for estimation **Event.detect**`(t)` : Evaluate the event function and decide if an event has occurred. - `t` — evaluation time for detection **Event.resolve**`(t)` : Resolve the event and record the time (t) at which it occurs. - `t` — evaluation time for event resolution **Event.to_checkpoint**`(prefix)` : Serialize event state for checkpointing. - `prefix` — key prefix for NPZ arrays (assigned by simulation) **Event.load_checkpoint**`(prefix, json_data, npz)` : Restore event state from checkpoint. - `prefix` — key prefix for NPZ arrays (assigned by simulation) - `json_data` — event metadata from checkpoint JSON - `npz` — numpy arrays from checkpoint NPZ #### pathsim.events.condition ##### class Condition(pathsim.events._event.Event) Subclass of base 'Event' that triggers if the event function evaluates to 'True', **Condition.detect**`(t)` : Evaluate the event function and check if condition is satisfied. - `t` — evaluation time for detection **Condition.resolve**`(t)` : Resolve the event and record the time (t) at which it occurs. - `t` — evaluation time for event resolution #### pathsim.events.schedule ##### class Schedule(pathsim.events._event.Event) Subclass of base 'Event' that triggers dependent on the evaluation time. **Parameters:** - `t_start, default=0` — starting time for schedule - `t_end, default=None` — termination time for schedule - `t_period, default=1` — time period of schedule, when events are triggered - `func_act, default=None` — action function for event resolution - `tolerance, default=TOLERANCE` — tolerance to check if detection is close to actual event **Attributes:** - `t_start` - `t_period` - `t_end` **Schedule.__init__**`(t_start = 0, t_end = None, t_period = 1, func_act = None, tolerance = TOLERANCE)` - `t_start, default=0` - `t_end, default=None` - `t_period, default=1` - `func_act, default=None` - `tolerance, default=TOLERANCE` **Schedule.estimate**`(t)` : Estimate the time until the next scheduled event. - `t` — evaluation time for estimation **Schedule.buffer**`(t)` : Buffer the current time to history - `t` — buffer time **Schedule.detect**`(t)` : Check if the event condition is satisfied, i.e. if the - `t` — evaluation time for detection ##### class ScheduleList(pathsim.events.schedule.Schedule) Subclass of base 'Schedule' that triggers dependent on the evaluation time. **Parameters:** - `times_evt` — list of event times in ascending order - `func_act, default=None` — action function for event resolution - `tolerance, default=TOLERANCE` — tolerance to check if detection is close to actual event **Attributes:** - `times_evt` **ScheduleList.__init__**`(times_evt, func_act = None, tolerance = TOLERANCE)` - `times_evt` - `func_act, default=None` - `tolerance, default=TOLERANCE` **ScheduleList.detect**`(t)` : Check if the event condition is satisfied, i.e. if the - `t` — evaluation time for detection #### pathsim.events.zerocrossing ##### class ZeroCrossing(pathsim.events._event.Event) Subclass of base 'Event' that triggers if the event function crosses zero. **ZeroCrossing.detect**`(t)` : Evaluate the event function and check for zero-crossings - `t` — evaluation time for detection ##### class ZeroCrossingUp(pathsim.events._event.Event) Modification of standard 'ZeroCrossing' event where events are only triggered **ZeroCrossingUp.detect**`(t)` : Evaluate the event function and check for zero-crossings - `t` — evaluation time for detection ##### class ZeroCrossingDown(pathsim.events._event.Event) Modification of standard 'ZeroCrossing' event where events are only triggered **ZeroCrossingDown.detect**`(t)` : Evaluate the event function and check for zero-crossings - `t` — evaluation time for detection #### pathsim.optim.anderson ##### class Anderson Anderson acceleration for fixed-point iteration. **Parameters:** - `m, default=OPT_HISTORY` — buffer depth (number of stored iterates) - `restart, default=OPT_RESTART` — if True, clear the buffer once it reaches depth ``m`` **Attributes:** - `m` - `restart` - `dx_buffer` - `dr_buffer` - `x_prev` - `r_prev` **Anderson.__init__**`(m = OPT_HISTORY, restart = OPT_RESTART)` - `m, default=OPT_HISTORY` - `restart, default=OPT_RESTART` **Anderson.solve**`(func, x0, iterations_max = 100, tolerance = 1e-06)` : Solve the function 'func' with initial - `func` — function to solve - `x0` — starting value for solution - `iterations_max, default=100` — maximum number of solver iterations - `tolerance, default=1e-06` — convergence condition **Anderson.reset**`()` : reset the anderson accelerator **Anderson.step**`(x, g)` : Perform one iteration on the fixed-point solution. - `x` — current solution - `g` — current evaluation of g(x) ##### class NewtonAnderson(pathsim.optim.anderson.Anderson) Hybrid Newton--Anderson fixed-point solver. **NewtonAnderson.solve**`(func, x0, jac = None, iterations_max = 100, tolerance = 1e-06)` : Solve the function 'func' with initial value - `func` — function to solve - `x0` — starting value for solution - `jac, default=None` — jacobian of 'func' - `iterations_max, default=100` — maximum number of solver iterations - `tolerance, default=1e-06` — convergence condition **NewtonAnderson.step**`(x, g, jac = None)` : Perform one iteration on the fixed-point solution. - `x` — current solution - `g` — current evaluation of g(x) - `jac, default=None` — evaluation of jacobian of 'g' #### pathsim.optim.booster ##### class ConnectionBooster Wraps a `Connection` instance and injects a fixed point accelerator. **Parameters:** - `connection` — connection instance to be boosted with an algebraic loop accelerator **Attributes:** - `connection` - `history` - `accelerator` **ConnectionBooster.__init__**`(connection)` - `connection` **ConnectionBooster.get**`()` : Return the output values of the source block that is referenced in **ConnectionBooster.set**`(val)` : Set targets input values. - `val` — input values to set at inputs of the targets, referenced by the connection **ConnectionBooster.reset**`()` : Reset the internal fixed point accelerator and update the history **ConnectionBooster.update**`()` : Wraps the `Connection.update` method for data transfer from source #### pathsim.optim.numerical ##### num_jac`(func, x, r = 0.001, tol = TOLERANCE)` Numerically computes the jacobian of the function 'func' ##### num_autojac`(func)` Wraps a function object such that it computes the jacobian #### pathsim.optim.operator ##### class Operator(object) Operator class for function evaluation and linearization. **Parameters:** - `func` — The function to wrap - `jac, default=None` — Optional analytical Jacobian of func. If None, automatic or numerical differentiation will be used. **Attributes:** - `f0` - `x0` - `J` **Operator.__init__**`(func, jac = None)` - `func` - `jac, default=None` **Operator.jac**`(x)` : Compute the Jacobian matrix at point x. - `x` — Point at which to evaluate the Jacobian Returns ------- **Operator.linearize**`(x)` : Linearize the function at point x. - `x` — Point at which to linearize the function **Operator.reset**`()` : Reset the linearization. ##### class DynamicOperator(object) Operator class for dynamic system function evaluation and linearization. **Parameters:** - `func` — The function to wrap with signature func(x, u, t) - `jac_x, default=None` — Optional analytical Jacobian with respect to x. If None, automatic or numerical differentiation will be used. - `jac_u, default=None` — Optional analytical Jacobian with respect to u. If None, automatic or numerical differentiation will be used. **Attributes:** - `f0` - `x0` - `u0` - `Jx` - `Ju` **DynamicOperator.__init__**`(func, jac_x = None, jac_u = None)` - `func` - `jac_x, default=None` - `jac_u, default=None` **DynamicOperator.jac_x**`(x, u, t)` : Compute the Jacobian matrix with respect to x. - `x` — State vector - `u` — Input vector - `t` — Time Returns ------- **DynamicOperator.jac_u**`(x, u, t)` : Compute the Jacobian matrix with respect to u. - `x` — State vector - `u` — Input vector - `t` — Time Returns ------- **DynamicOperator.linearize**`(x, u, t)` : Linearize the function at point (x, u, t). - `x` — State vector - `u` — Input vector - `t` — Time **DynamicOperator.reset**`()` : Reset the linearization. #### pathsim.solvers._rungekutta ##### class ExplicitRungeKutta(pathsim.solvers._solver.ExplicitSolver) Base class for explicit Runge-Kutta integrators which implements **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `s` - `beta` - `Ks` - `BT` - `TR` **ExplicitRungeKutta.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **ExplicitRungeKutta.error_controller**`(dt)` : Compute scaling factor for adaptive timestep based on - `dt` — integration timestep **ExplicitRungeKutta.step**`(f, dt)` : Performs the (explicit) timestep at the intermediate RK stages - `f` — evaluation of function - `dt` — integration timestep ##### class DiagonallyImplicitRungeKutta(pathsim.solvers._solver.ImplicitSolver) Base class for diagonally implicit Runge-Kutta (DIRK) integrators **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `s` - `beta` - `Ks` - `BT` - `A` - `TR` **DiagonallyImplicitRungeKutta.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **DiagonallyImplicitRungeKutta.error_controller**`(dt)` : Compute scaling factor for adaptive timestep based on - `dt` — integration timestep **DiagonallyImplicitRungeKutta.solve**`(f, J, dt)` : Solves the implicit update equation using the optimizer of the engine. - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep **DiagonallyImplicitRungeKutta.step**`(f, dt)` : performs the (explicit) timestep at the intermediate RK stages - `f` — evaluation of function - `dt` — integration timestep #### pathsim.solvers._solver ##### class Solver Base skeleton class for solver definition. Defines the basic solver methods and **Parameters:** - `initial_value, default=0` — initial condition / integration constant - `parent, default=None` — parent solver instance that manages the intermediate stages, stage counter, etc. - `tolerance_lte_abs, default=SOL_TOLERANCE_LTE_ABS` — absolute tolerance for local truncation error (for solvers with error estimate) - `tolerance_lte_rel, default=SOL_TOLERANCE_LTE_REL` — relative tolerance for local truncation error (for solvers with error estimate) **Attributes:** - `initial_value` - `x` - `tolerance_lte_abs` - `tolerance_lte_rel` - `parent` - `is_adaptive` - `history` - `n` - `s` - `eval_stages` - `stage` — stage property management to interface with parent solver - `state` — Property for cleaner access to internal state. **Solver.__init__**`(initial_value = 0, parent = None, tolerance_lte_abs = SOL_TOLERANCE_LTE_ABS, tolerance_lte_rel = SOL_TOLERANCE_LTE_REL)` - `initial_value, default=0` - `parent, default=None` - `tolerance_lte_abs, default=SOL_TOLERANCE_LTE_ABS` - `tolerance_lte_rel, default=SOL_TOLERANCE_LTE_REL` **Solver.is_first_stage**`()` **Solver.is_last_stage**`()` **Solver.stages**`(t, dt)` : Generator that yields the intermediate evaluation - `t` — evaluation time - `dt` — integration timestep **Solver.get**`()` : Returns current internal state of the solver. **Solver.set**`(x)` : Sets the internal state of the integration engine. - `x` — new internal state of the solver **Solver.reset**`(initial_value = None)` : "Resets integration engine to initial value, - `initial_value, default=None` — new initial value of the engine, optional **Solver.buffer**`(dt)` : Saves the current state to an internal state buffer which - `dt` — integration timestep **Solver.cast**`(cls, other, parent, solver_kwargs = {})` : Cast the integration engine to the new type and initialize - `other` — solver instance to cast to new solver type - `parent` — solver instance to use as parent - `solver_kwargs, default={}` — additional args for the new solver **Solver.create**`(cls, initial_value, parent = None, from_engine = None, solver_kwargs = {})` : Create a new solver instance, optionally inheriting state from existing engine. - `initial_value` — initial condition / integration constant - `parent, default=None` — parent solver instance for stage synchronization - `from_engine, default=None` — existing solver to inherit state and settings from - `solver_kwargs, default={}` — additional args for the solver (tolerances, etc.) **Solver.to_checkpoint**`(prefix)` : Serialize solver state for checkpointing. - `prefix` — NPZ key prefix for this solver's arrays **Solver.load_checkpoint**`(json_data, npz, prefix)` : Restore solver state from checkpoint. - `json_data` — solver metadata from checkpoint JSON - `npz` — numpy arrays from checkpoint NPZ - `prefix` — NPZ key prefix for this solver's arrays **Solver.error_controller**`()` : Returns the estimated local truncation error (abs and rel) and scaling factor **Solver.revert**`()` : Revert integration engine to previous timestep. **Solver.step**`(f, dt)` : Performs the explicit timestep for (t+dt) based - `f` — evaluation of rhs function - `dt` — integration timestep **Solver.interpolate**`(r, dt)` : Interpolate solution after successful timestep as a ratio - `r` — ration for interpolation within timestep - `dt` — integration timestep ##### class ExplicitSolver(pathsim.solvers._solver.Solver) Base class for explicit solver definition. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `is_explicit` - `is_implicit` - `eval_stages` **ExplicitSolver.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **ExplicitSolver.integrate_singlestep**`(func, time = 0.0, dt = SIM_TIMESTEP)` : Directly integrate the function for a single timestep 'dt' with - `func` — function to integrate f(x, t) - `time, default=0.0` — starting time for timestep - `dt, default=SIM_TIMESTEP` — integration timestep **ExplicitSolver.integrate**`(func, time_start = 0.0, time_end = 1.0, dt = SIM_TIMESTEP, dt_min = SIM_TIMESTEP_MIN, dt_max = SIM_TIMESTEP_MAX, adaptive = True)` : Directly integrate the function 'func' from 'time_start' - `func` — function to integrate f(x, t) - `time_start, default=0.0` — starting time for integration - `time_end, default=1.0` — end time for integration - `dt, default=SIM_TIMESTEP` — timestep or initial timestep for adaptive solvers - `dt_min, default=SIM_TIMESTEP_MIN` — lower bound for timestep, default '0.0' - `dt_max, default=SIM_TIMESTEP_MAX` — upper bound for timestep, default 'None' - `adaptive, default=True` — use adaptive timestepping if available ##### class ImplicitSolver(pathsim.solvers._solver.Solver) Base class for implicit solver definition. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `is_explicit` - `is_implicit` - `eval_stages` - `opt` **ImplicitSolver.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **ImplicitSolver.buffer**`(dt)` : Saves the current state to an internal state buffer which - `dt` — integration timestep **ImplicitSolver.solve**`(j, J, dt)` : Advances the solution of the implicit update equation of the solver - `j` - `J` — evaluation of jacobian of rhs function - `dt` — integration timestep **ImplicitSolver.integrate_singlestep**`(func, jac, time = 0.0, dt = SIM_TIMESTEP, tolerance_fpi = SOL_TOLERANCE_FPI, max_iterations = SOL_ITERATIONS_MAX)` : Directly integrate the function 'func' for a single timestep 'dt' with - `func` — function to integrate f(x, t) - `jac` — jacobian of f w.r.t. x - `time, default=0.0` - `dt, default=SIM_TIMESTEP` — integration timestep - `tolerance_fpi, default=SOL_TOLERANCE_FPI` — convergence criterion for implicit update equation - `max_iterations, default=SOL_ITERATIONS_MAX` — maximum numer of iterations for optimizer to solve implicit update equation **ImplicitSolver.integrate**`(func, jac, time_start = 0.0, time_end = 1.0, dt = SIM_TIMESTEP, dt_min = SIM_TIMESTEP_MIN, dt_max = SIM_TIMESTEP_MAX, adaptive = True, tolerance_fpi = SOL_TOLERANCE_FPI, max_iterations = SOL_ITERATIONS_MAX)` : Directly integrate the function 'func' from 'time_start' - `func` — function to integrate f(x, t) - `jac` — jacobian of f w.r.t. x - `time_start, default=0.0` — starting time for integration - `time_end, default=1.0` — end time for integration - `dt, default=SIM_TIMESTEP` — timestep or initial timestep for adaptive solvers - `dt_min, default=SIM_TIMESTEP_MIN` — lower bound for timestep, default '0.0' - `dt_max, default=SIM_TIMESTEP_MAX` — upper bound for timestep, default 'None' - `adaptive, default=True` — use adaptive timestepping if available - `tolerance_fpi, default=SOL_TOLERANCE_FPI` — convergence criterion for implicit update equation - `max_iterations, default=SOL_ITERATIONS_MAX` — maximum numer of iterations for optimizer to solve implicit update equation #### pathsim.solvers.bdf ##### class BDF(pathsim.solvers._solver.ImplicitSolver) Base class for the backward differentiation formula (BDF) integrators. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `K` - `F` - `startup` **BDF.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **BDF.cast**`(cls, other, parent, solver_kwargs = {})` : cast to this solver needs special handling of startup method - `other` — solver instance to cast new instance of this class from - `parent` — solver instance to use as parent - `solver_kwargs, default={}` — other args for the solver **BDF.create**`(cls, initial_value, parent = None, from_engine = None, solver_kwargs = {})` : Create a new BDF solver, properly initializing the startup solver. - `initial_value` — initial condition / integration constant - `parent, default=None` — parent solver instance for stage synchronization - `from_engine, default=None` — existing solver to inherit state and settings from - `solver_kwargs, default={}` — additional args for the solver **BDF.stages**`(t, dt)` : Generator that yields the intermediate evaluation - `t` — evaluation time - `dt` — integration timestep **BDF.reset**`(initial_value = None)` : "Resets integration engine to initial value, - `initial_value, default=None` — new initial value of the engine, optional **BDF.buffer**`(dt)` : buffer the state for the multistep method - `dt` — integration timestep **BDF.solve**`(f, J, dt)` : Solves the implicit update equation using the optimizer of the engine. - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep **BDF.step**`(f, dt)` : Performs the explicit timestep for (t+dt) based - `f` — evaluation of rhs function - `dt` — integration timestep ##### class BDF2(pathsim.solvers.bdf.BDF) Fixed-step 2nd order BDF method. A-stable. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` **BDF2.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class BDF3(pathsim.solvers.bdf.BDF) Fixed-step 3rd order BDF method. :math:`A(\alpha)`-stable with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` **BDF3.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class BDF4(pathsim.solvers.bdf.BDF) Fixed-step 4th order BDF method. :math:`A(\alpha)`-stable with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` **BDF4.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class BDF5(pathsim.solvers.bdf.BDF) Fixed-step 5th order BDF method. :math:`A(\alpha)`-stable with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` **BDF5.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class BDF6(pathsim.solvers.bdf.BDF) Fixed-step 6th order BDF method. **Not** A-stable **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` **BDF6.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.dirk2 ##### class DIRK2(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Two-stage, 2nd order DIRK method. L-stable, SSP-optimal, symplectic. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` - `A` **DIRK2.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.dirk3 ##### class DIRK3(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Four-stage, 3rd order L-stable DIRK method. Stiffly accurate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **DIRK3.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.esdirk32 ##### class ESDIRK32(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Four-stage, 3rd order ESDIRK method with embedded 2nd order error **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **ESDIRK32.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.esdirk4 ##### class ESDIRK4(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Six-stage, 4th order ESDIRK method. L-stable and stiffly accurate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **ESDIRK4.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.esdirk43 ##### class ESDIRK43(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Six-stage, 4th order ESDIRK method with embedded 3rd order error **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **ESDIRK43.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.esdirk54 ##### class ESDIRK54(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Seven-stage, 5th order ESDIRK method with embedded 4th order error **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **ESDIRK54.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.esdirk85 ##### class ESDIRK85(pathsim.solvers._rungekutta.DiagonallyImplicitRungeKutta) Sixteen-stage, 8th order ESDIRK method with embedded 5th order error **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **ESDIRK85.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.euler ##### class EUF(pathsim.solvers._solver.ExplicitSolver) Explicit forward Euler method. First-order, single-stage. **EUF.step**`(f, dt)` : performs the explicit forward timestep for (t+dt) - `f` — evaluation of function - `dt` — integration timestep ##### class EUB(pathsim.solvers._solver.ImplicitSolver) Implicit backward Euler method. First-order, A-stable and L-stable. **EUB.solve**`(f, J, dt)` : Solves the implicit update equation - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep #### pathsim.solvers.gear ##### class GEAR(pathsim.solvers._solver.ImplicitSolver) Base class for GEAR-type integrators that defines the universal methods. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `beta` - `history_dt` - `is_adaptive` - `startup` **GEAR.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **GEAR.cast**`(cls, other, parent, solver_kwargs = {})` : cast to this solver needs special handling of startup method - `other` — solver instance to cast new instance of this class from - `parent` — solver instance to use as parent - `solver_kwargs, default={}` — other args for the solver **GEAR.create**`(cls, initial_value, parent = None, from_engine = None, solver_kwargs = {})` : Create a new GEAR solver, properly initializing the startup solver. - `initial_value` — initial condition / integration constant - `parent, default=None` — parent solver instance for stage synchronization - `from_engine, default=None` — existing solver to inherit state and settings from - `solver_kwargs, default={}` — additional args for the solver **GEAR.to_checkpoint**`(prefix)` : Serialize GEAR solver state including startup solver and timestep history. - `prefix` **GEAR.load_checkpoint**`(json_data, npz, prefix)` : Restore GEAR solver state including startup solver and timestep history. - `json_data` - `npz` - `prefix` **GEAR.stages**`(t, dt)` : Generator that yields the intermediate evaluation - `t` — evaluation time - `dt` — integration timestep **GEAR.reset**`(initial_value = None)` : "Resets integration engine to initial value, - `initial_value, default=None` — new initial value of the engine, optional **GEAR.buffer**`(dt)` : Buffer the state and timestep. Dynamically precompute - `dt` — integration timestep **GEAR.revert**`()` : Revert integration engine to previous timestep, this is only **GEAR.error_controller**`(tr)` : Compute scaling factor for adaptive timestep based on absolute and - `tr` — truncation error estimate **GEAR.solve**`(f, J, dt)` : Solves the implicit update equation using the optimizer of the engine. - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep **GEAR.step**`(f, dt)` : Finalizes the timestep by resetting the solver for the implicit - `f` — evaluation of function - `dt` — integration timestep ##### class GEAR21(pathsim.solvers.gear.GEAR) Variable-step 2nd order BDF with 1st order error estimate. A-stable. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `history` - `history_dt` **GEAR21.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class GEAR32(pathsim.solvers.gear.GEAR) Variable-step 3rd order BDF with 2nd order error estimate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `history` - `history_dt` **GEAR32.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class GEAR43(pathsim.solvers.gear.GEAR) Variable-step 4th order BDF with 3rd order error estimate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `history` - `history_dt` **GEAR43.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class GEAR54(pathsim.solvers.gear.GEAR) Variable-step 5th order BDF with 4th order error estimate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `m` - `history` - `history_dt` **GEAR54.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` ##### class GEAR52A(pathsim.solvers.gear.GEAR) Variable-step, variable-order BDF (orders 2--5). Adapts both timestep **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `n` - `history` - `history_dt` **GEAR52A.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **GEAR52A.buffer**`(dt)` : Buffer the state and timestep. Dynamically precompute - `dt` — integration timestep **GEAR52A.error_controller**`(tr_m, tr_p)` : Compute scaling factor for adaptive timestep based on absolute and - `tr_m` — lower order truncation error estimate - `tr_p` — higher order truncation error estimate **GEAR52A.solve**`(f, J, dt)` : Solves the implicit update equation using the optimizer of the engine. - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep **GEAR52A.step**`(f, dt)` : Finalizes the timestep by resetting the solver for the implicit - `f` — evaluation of function - `dt` — integration timestep ##### compute_bdf_coefficients`(order, timesteps)` Computes the coefficients for backward differentiation formulas for a given order. #### pathsim.solvers.rk4 ##### class RK4(pathsim.solvers._rungekutta.ExplicitRungeKutta) Classical four-stage, 4th order explicit Runge-Kutta method. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **RK4.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **RK4.interpolate**`(r, dt)` - `r` - `dt` #### pathsim.solvers.rkbs32 ##### class RKBS32(pathsim.solvers._rungekutta.ExplicitRungeKutta) Bogacki-Shampine 3(2) pair. Four-stage, 3rd order with FSAL property. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKBS32.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkck54 ##### class RKCK54(pathsim.solvers._rungekutta.ExplicitRungeKutta) Cash-Karp 5(4) pair. Six stages, 5th order with embedded 4th order **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKCK54.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkdp54 ##### class RKDP54(pathsim.solvers._rungekutta.ExplicitRungeKutta) Dormand-Prince 5(4) pair (DOPRI5). Seven stages, 5th order with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKDP54.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkdp87 ##### class RKDP87(pathsim.solvers._rungekutta.ExplicitRungeKutta) Dormand-Prince 8(7) pair (DOP853). Thirteen stages, 8th order with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKDP87.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkf21 ##### class RKF21(pathsim.solvers._rungekutta.ExplicitRungeKutta) Three-stage, 2nd order Runge-Kutta-Fehlberg method with embedded 1st order error estimate. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKF21.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkf45 ##### class RKF45(pathsim.solvers._rungekutta.ExplicitRungeKutta) Runge-Kutta-Fehlberg 4(5) pair. Six stages, 4th order propagation with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKF45.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkf78 ##### class RKF78(pathsim.solvers._rungekutta.ExplicitRungeKutta) Runge-Kutta-Fehlberg 7(8) pair. Thirteen stages, 7th order propagation **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKF78.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.rkv65 ##### class RKV65(pathsim.solvers._rungekutta.ExplicitRungeKutta) Verner 6(5) "most robust" pair. Nine stages, 6th order with **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `m` - `is_adaptive` - `eval_stages` - `BT` - `TR` **RKV65.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.ssprk22 ##### class SSPRK22(pathsim.solvers._rungekutta.ExplicitRungeKutta) Two-stage, 2nd order Strong Stability Preserving (SSP) Runge-Kutta method. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **SSPRK22.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **SSPRK22.interpolate**`(r, dt)` - `r` - `dt` #### pathsim.solvers.ssprk33 ##### class SSPRK33(pathsim.solvers._rungekutta.ExplicitRungeKutta) Three-stage, 3rd order optimal SSP Runge-Kutta method. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **SSPRK33.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` **SSPRK33.interpolate**`(r, dt)` - `r` - `dt` #### pathsim.solvers.ssprk34 ##### class SSPRK34(pathsim.solvers._rungekutta.ExplicitRungeKutta) Four-stage, 3rd order SSP Runge-Kutta method with SSP coefficient 2. **Parameters:** - `solver_args, default=()` - `solver_kwargs, default={}` **Attributes:** - `s` - `n` - `eval_stages` - `BT` **SSPRK34.__init__**`(solver_args = (), solver_kwargs = {})` - `solver_args, default=()` - `solver_kwargs, default={}` #### pathsim.solvers.steadystate ##### class SteadyState(pathsim.solvers._solver.ImplicitSolver) Pseudo-solver for computing the DC operating point (steady state). **SteadyState.solve**`(f, J, dt)` : Solve for steady state by finding x where f(x,u,t) = 0 - `f` — evaluation of function - `J` — evaluation of jacobian of function - `dt` — integration timestep #### pathsim.utils.adaptivebuffer ##### class AdaptiveBuffer A class that manages an adaptive buffer for delay modeling which is primarily **Parameters:** - `delay` — time delay in seconds **Attributes:** - `delay` - `buffer_t` - `buffer_v` - `ns` **AdaptiveBuffer.__init__**`(delay)` - `delay` **AdaptiveBuffer.add**`(t, value)` : adding a new datapoint to the buffer - `t` — time to add - `value` — numerical value to add **AdaptiveBuffer.interp**`(t)` : interpolate buffer at defined lookup time - `t` — time for interpolation **AdaptiveBuffer.get**`(t)` : lookup datapoint from buffer with - `t` — time for lookup with delay **AdaptiveBuffer.clear**`()` : clear the buffer, reset everything **AdaptiveBuffer.to_checkpoint**`(prefix)` : Serialize buffer state for checkpointing. - `prefix` — NPZ key prefix **AdaptiveBuffer.load_checkpoint**`(npz, prefix)` : Restore buffer state from checkpoint. - `npz` — numpy arrays from checkpoint NPZ - `prefix` — NPZ key prefix #### pathsim.utils.analysis ##### class Timer(contextlib.ContextDecorator) Context manager that times the execution time **Parameters:** - `verbose, default=True` — flag for verbose output (uses logging at DEBUG level) **Attributes:** - `verbose` - `time` - `logger` **Timer.__init__**`(verbose = True)` - `verbose, default=True` ##### class Profiler(contextlib.ContextDecorator) Context manager for easy code profiling **Parameters:** - `top_n, default=50` — track top n function calls - `sort_by, default='cumulative'` — method to sort function cally by **Attributes:** - `top_n` - `sort_by` - `profiler` **Profiler.__init__**`(top_n = 50, sort_by = 'cumulative')` - `top_n, default=50` - `sort_by, default='cumulative'` ##### timer`(func)` Shows the execution time in milliseconds of the #### pathsim.utils.deprecation ##### deprecated`(version = None, replacement = None, reason = None)` Decorator to mark functions, methods, or classes as deprecated. ##### _prepend_deprecation_notice`(docstring, notice)` Prepend deprecation notice to docstring. #### pathsim.utils.fmuwrapper ##### class EventInfo Unified event information structure for both FMI 2.0 and 3.0. **Parameters:** - `discrete_states_need_update (bool), default=False` — whether discrete state iteration is needed - `terminate_simulation (bool), default=False` — whether FMU requests simulation termination - `nominals_changed (bool), default=False` — whether nominal values of continuous states changed - `values_changed (bool), default=False` — whether continuous state values changed - `next_event_time_defined (bool), default=False` — whether FMU has scheduled a next time event - `next_event_time (float), default=0.0` — time of next scheduled event (if defined) **Attributes:** - `discrete_states_need_update: bool` - `terminate_simulation: bool` - `nominals_changed: bool` - `values_changed: bool` - `next_event_time_defined: bool` - `next_event_time: float` **EventInfo.__init__**`(discrete_states_need_update: bool = False, terminate_simulation: bool = False, nominals_changed: bool = False, values_changed: bool = False, next_event_time_defined: bool = False, next_event_time: float = 0.0)` - `discrete_states_need_update, default=False` - `terminate_simulation, default=False` - `nominals_changed, default=False` - `values_changed, default=False` - `next_event_time_defined, default=False` - `next_event_time, default=0.0` ##### class StepResult Result information from a co-simulation step. **Parameters:** - `event_encountered (bool), default=False` — whether an event was encountered during step (FMI 3.0 only) - `terminate_simulation (bool), default=False` — whether FMU requests simulation termination (FMI 3.0 only) - `early_return (bool), default=False` — whether step returned early (FMI 3.0 only) - `last_successful_time (float), default=0.0` — last time successfully reached (FMI 3.0 only) **Attributes:** - `event_encountered: bool` - `terminate_simulation: bool` - `early_return: bool` - `last_successful_time: float` **StepResult.__init__**`(event_encountered: bool = False, terminate_simulation: bool = False, early_return: bool = False, last_successful_time: float = 0.0)` - `event_encountered, default=False` - `terminate_simulation, default=False` - `early_return, default=False` - `last_successful_time, default=0.0` ##### class _FMI2Ops FMI 2.0 specific operations. **_FMI2Ops.set_real**`(fmu, refs, values)` - `fmu` - `refs` - `values` **_FMI2Ops.get_real**`(fmu, refs)` - `fmu` - `refs` **_FMI2Ops.set_integer**`(fmu, refs, values)` - `fmu` - `refs` - `values` **_FMI2Ops.get_integer**`(fmu, refs)` - `fmu` - `refs` **_FMI2Ops.do_step**`(fmu, current_time, step_size)` - `fmu` - `current_time` - `step_size` **_FMI2Ops.get_derivatives**`(fmu, n_states)` - `fmu` - `n_states` **_FMI2Ops.update_discrete_states**`(fmu)` - `fmu` **_FMI2Ops.setup_experiment**`(fmu, tolerance, start_time, stop_time)` - `fmu` - `tolerance` - `start_time` - `stop_time` **_FMI2Ops.enter_initialization_mode**`(fmu, tolerance, start_time, stop_time)` - `fmu` - `tolerance` - `start_time` - `stop_time` **_FMI2Ops.exit_initialization_mode**`(fmu, mode)` - `fmu` - `mode` ##### class _FMI3Ops FMI 3.0 specific operations. **_FMI3Ops.set_real**`(fmu, refs, values)` - `fmu` - `refs` - `values` **_FMI3Ops.get_real**`(fmu, refs)` - `fmu` - `refs` **_FMI3Ops.set_integer**`(fmu, refs, values)` - `fmu` - `refs` - `values` **_FMI3Ops.get_integer**`(fmu, refs)` - `fmu` - `refs` **_FMI3Ops.do_step**`(fmu, current_time, step_size)` - `fmu` - `current_time` - `step_size` **_FMI3Ops.get_derivatives**`(fmu, n_states)` - `fmu` - `n_states` **_FMI3Ops.update_discrete_states**`(fmu)` - `fmu` **_FMI3Ops.setup_experiment**`(fmu, tolerance, start_time, stop_time)` - `fmu` - `tolerance` - `start_time` - `stop_time` **_FMI3Ops.enter_initialization_mode**`(fmu, tolerance, start_time, stop_time)` - `fmu` - `tolerance` - `start_time` - `stop_time` **_FMI3Ops.exit_initialization_mode**`(fmu, mode)` - `fmu` - `mode` ##### class FMUWrapper Version-agnostic wrapper for FMI 2.0 and 3.0 FMUs. **Parameters:** - `fmu_path` — path to the FMU file (.fmu) - `instance_name, default='fmu_instance'` — name for the FMU instance (default: 'fmu_instance') - `mode, default='cosimulation'` — FMU interface mode: 'cosimulation' or 'model_exchange' (default: 'cosimulation') **Attributes:** - `fmu_path` - `instance_name` - `mode` - `model_description` - `fmi_version` - `unzipdir` - `n_states` - `n_event_indicators` - `fmu` - `default_step_size: Optional[float]` — Get default step size from FMU's default experiment, if defined. - `default_tolerance: Optional[float]` — Get default tolerance from FMU's default experiment, if defined. - `needs_completed_integrator_step: bool` — Check if FMU requires completedIntegratorStep notifications (Model Exchange only). - `provides_jacobian: bool` — Check if FMU provides directional derivatives for Jacobian computation. **FMUWrapper.__init__**`(fmu_path, instance_name = 'fmu_instance', mode = 'cosimulation')` - `fmu_path` - `instance_name, default='fmu_instance'` - `mode, default='cosimulation'` **FMUWrapper.create_port_registers**`()` : Create input and output registers for block I/O. **FMUWrapper.initialize**`(start_values = None, start_time = 0.0, stop_time = None, tolerance = None)` : Complete FMU initialization sequence. - `start_values, default=None` — dictionary of variable names and their initial values - `start_time, default=0.0` — simulation start time (default: 0.0) - `stop_time, default=None` — simulation stop time - `tolerance, default=None` — tolerance for integration/event detection **FMUWrapper.get_state_jacobian**`()` : Compute Jacobian of state derivatives w.r.t. states (Model Exchange only). **FMUWrapper.instantiate**`(visible = False, logging_on = False)` : Instantiate the FMU. - `visible, default=False` - `logging_on, default=False` **FMUWrapper.setup_experiment**`(tolerance = None, start_time = 0.0, stop_time = None)` : Setup experiment parameters. - `tolerance, default=None` - `start_time, default=0.0` - `stop_time, default=None` **FMUWrapper.enter_initialization_mode**`()` : Enter initialization mode. **FMUWrapper.exit_initialization_mode**`()` : Exit initialization mode and return event information. **FMUWrapper.reset**`()` : Reset FMU to initial state. **FMUWrapper.terminate**`()` : Terminate FMU. **FMUWrapper.free_instance**`()` : Free FMU instance and resources. **FMUWrapper.set_real**`(refs, values)` : Set real-valued variables by reference. - `refs` - `values` **FMUWrapper.get_real**`(refs)` : Get real-valued variables by reference. - `refs` **FMUWrapper.set_variable**`(name, value)` : Set a single variable by name (automatically detects type). - `name` - `value` **FMUWrapper.set_inputs_from_array**`(values)` : Set all FMU inputs from an array. - `values` **FMUWrapper.get_outputs_as_array**`()` : Get all FMU outputs as an array. **FMUWrapper.do_step**`(current_time, step_size)` : Perform a co-simulation step. - `current_time` - `step_size` **FMUWrapper.set_time**`(time)` : Set current time (Model Exchange only). - `time` **FMUWrapper.set_continuous_states**`(states)` : Set continuous states (Model Exchange only). - `states` **FMUWrapper.get_continuous_states**`()` : Get continuous states (Model Exchange only). **FMUWrapper.get_derivatives**`()` : Get state derivatives (Model Exchange only). **FMUWrapper.get_event_indicators**`()` : Get event indicators (Model Exchange only). **FMUWrapper.enter_event_mode**`()` : Enter event mode (Model Exchange only). **FMUWrapper.enter_continuous_time_mode**`()` : Enter continuous time mode (Model Exchange only). **FMUWrapper.update_discrete_states**`()` : Update discrete states during event iteration (Model Exchange only). **FMUWrapper.completed_integrator_step**`()` : Notify FMU that integrator step completed (Model Exchange only). #### pathsim.utils.gilbert ##### gilbert_realization`(Poles = [], Residues = [], Const = 0.0, tolerance = 1e-09)` Build real valued statespace model from transfer function #### pathsim.utils.graph ##### class Graph Optimized graph representation with efficient assembly and cycle detection. **Parameters:** - `blocks, default=None` — list of block objects to include in the graph - `connections, default=None` — list of Connection objects defining the graph edges **Attributes:** - `blocks` - `connections` - `has_loops` - `size` — Returns the size of the graph as (number of blocks, number of connections). - `depth` — Returns the depths of the graph as (algebraic depth, loop depth). **Graph.__init__**`(blocks = None, connections = None)` - `blocks, default=None` - `connections, default=None` **Graph.is_algebraic_path**`(start_block, end_block)` : Check if blocks are connected through an algebraic path. - `start_block` — starting block of the path - `end_block` — ending block of the path **Graph.outgoing_connections**`(block)` : Returns outgoing connections of a block. - `block` — block to get outgoing connections for **Graph.dag**`()` : Generator for DAG levels. **Graph.loop**`()` : Generator for loop DAG levels. **Graph.loop_closing_connections**`()` : Returns loop-closing connections. #### pathsim.utils.logger ##### class LoggerManager Singleton class for centralized logging configuration in PathSim. **Parameters:** - `enabled, default=False` — Whether logging is enabled. Defaults to False. - `output, default=None` — Output destination. If string, logs to file. If None, logs to stdout. Defaults to None. - `level, default=logging.INFO` — Logging level. Defaults to logging.INFO. - `format, default=None` — Log message format. Defaults to "%(asctime)s - %(levelname)s - %(message)s". - `date_format, default='%H:%M:%S'` — Date format for timestamps. Defaults to '%H:%M:%S'. **LoggerManager.__init__**`(enabled = False, output = None, level = logging.INFO, format = None, date_format = '%H:%M:%S')` : Initialize the logger manager and setup root logger. - `enabled, default=False` — Whether logging is enabled. Defaults to False. - `output, default=None` — Output destination. If string, logs to file. If None, logs to stdout. Defaults to None. - `level, default=logging.INFO` — Logging level. Defaults to logging.INFO. - `format, default=None` — Log message format. Defaults to "%(asctime)s - %(levelname)s - %(message)s". - `date_format, default='%H:%M:%S'` — Date format for timestamps. Defaults to '%H:%M:%S'. **LoggerManager.configure**`(enabled = True, output = None, level = logging.INFO, format = None, date_format = None)` : Configure the root PathSim logger and all child loggers. - `enabled, default=True` — Whether logging is enabled. If False, all logging is disabled. Defaults to True. - `output, default=None` — Output destination for logs. If a string, interpreted as a file path and logs are written to that file. If None, logs are written to stdout. Defaults to None (stdout). - `level, default=logging.INFO` — Logging level (e.g., logging.DEBUG, logging.INFO, logging.WARNING). Defaults to logging.INFO. - `format, default=None` — Log message format string. If None, uses default format. Defaults to "%(asctime)s - %(levelname)s - %(message)s". - `date_format, default=None` — Date format string for timestamps (e.g., '%H:%M:%S'). If None, uses default format. Defaults to None. **LoggerManager.get_logger**`(name)` : Get or create a logger with PathSim hierarchy. - `name` — Name of the logger, will be prefixed with 'pathsim.' to create hierarchical logger (e.g., 'simulation' -> 'pathsim.simulation'). **LoggerManager.set_level**`(level, module = None)` : Set logging level globally or for a specific module. - `level` — Logging level (e.g., logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL). - `module, default=None` — Module name to set level for (e.g., 'progress', 'analysis.timer'). If None, sets level for the root pathsim logger, affecting all child loggers that don't have their own level set. Defaults to None. **LoggerManager.is_enabled**`()` : Check if logging is currently enabled. **LoggerManager.get_effective_level**`(module = None)` : Get the effective logging level. - `module, default=None` — Module name to check level for. If None, returns root logger level. Defaults to None. #### pathsim.utils.mutable ##### _do_reinit`(block)` Re-run __init__ with current parameter values, preserving engine state. ##### mutable`(cls)` Class decorator that makes all ``__init__`` parameters trigger automatic #### pathsim.utils.portreference ##### class PortReference Container class that holds a reference to a block and a list of ports. **Parameters:** - `block, default=None` — internal block reference - `ports, default=None` — list of port indices or names **Attributes:** - `block` - `ports` **PortReference.__init__**`(block = None, ports = None)` - `block, default=None` - `ports, default=None` **PortReference.to**`(other)` : Transfer the data between two `PortReference` instances, - `other` — the `PortReference` instance to transfer data to from `self` **PortReference.get_inputs**`()` : Return the input values of the block at specified ports **PortReference.set_inputs**`(vals)` : Set the block inputs with values at specified ports - `vals` — values to set at block input ports **PortReference.get_outputs**`()` : Return the output values of the block at specified ports **PortReference.set_outputs**`(vals)` : Set the block outputs with values at specified ports - `vals` — values to set at block output ports **PortReference.to_dict**`()` : Serialization into dict #### pathsim.utils.progresstracker ##### class ProgressTracker A progress tracker for simulations with adaptive ETA and step rate display. **Parameters:** - `total_duration` — The total simulation duration to track against. Must be positive. - `description, default='Progress'` — Description for log messages. Defaults to "Progress". - `logger, default=None` — Logger instance. If None, uses LoggerManager. Defaults to None. - `log, default=True` — Enable logging. Defaults to True. - `log_level, default=logging.INFO` — Logging level. Defaults to logging.INFO. - `min_log_interval, default=LOG_MIN_INTERVAL` — Minimum seconds between logs. Defaults to LOG_MIN_INTERVAL. - `update_log_every, default=LOG_UPDATE_EVERY` — Log every N progress fraction (e.g., 0.2 = 20%). Defaults to LOG_UPDATE_EVERY. - `bar_width, default=20` — Progress bar width in characters. Defaults to 20. - `ema_alpha, default=0.3` — EMA smoothing factor (0-1), lower = more smoothing. Defaults to 0.3. **Attributes:** - `total_duration` - `description` - `log` - `log_level` - `min_log_interval` - `update_log_every` - `bar_width` - `ema_alpha` - `logger` - `start_time` - `stats` - `current_progress` — Current progress fraction (0.0 to 1.0) **ProgressTracker.__init__**`(total_duration, description = 'Progress', logger = None, log = True, log_level = logging.INFO, min_log_interval = LOG_MIN_INTERVAL, update_log_every = LOG_UPDATE_EVERY, bar_width = 20, ema_alpha = 0.3)` - `total_duration` - `description, default='Progress'` - `logger, default=None` - `log, default=True` - `log_level, default=logging.INFO` - `min_log_interval, default=LOG_MIN_INTERVAL` - `update_log_every, default=LOG_UPDATE_EVERY` - `bar_width, default=20` - `ema_alpha, default=0.3` **ProgressTracker.start**`()` : Start the progress tracker **ProgressTracker.update**`(progress, success = True, kwargs = {})` : Update progress and optionally log - `progress` — Progress fraction (0.0 to 1.0) - `success, default=True` — Whether this step was successful. Defaults to True. **kwargs Additional data (first key-value shown in logs if provided) - `kwargs, default={}` **ProgressTracker.interrupt**`()` : Mark tracker as interrupted **ProgressTracker.close**`()` : Close tracker and log final stats #### pathsim.utils.realtimeplotter ##### class RealtimePlotter Class that manages a realtime plotting window that **Parameters:** - `max_samples, default=None` — maximum number of samples to plot - `update_interval, default=1` — time in seconds between refreshs - `labels, default=[]` — labels for plot traces - `x_label, default=''` — label for x-axis - `y_label, default=''` — label for y-axis **Attributes:** - `max_samples` - `update_interval` - `labels` - `x_label` - `y_label` - `lines` - `data` - `last_update` - `is_running` - `legend` - `lined` **RealtimePlotter.__init__**`(max_samples = None, update_interval = 1, labels = [], x_label = '', y_label = '')` - `max_samples, default=None` - `update_interval, default=1` - `labels, default=[]` - `x_label, default=''` - `y_label, default=''` **RealtimePlotter.update_all**`(x, y)` : update the plot completely with new data - `x` — new x values to plot - `y` — new y values to plot **RealtimePlotter.update**`(x, y)` : update the plot with new data - `x` — new x value to add - `y` — new y value to add **RealtimePlotter.show**`()` **RealtimePlotter.on_close**`(event)` - `event` #### pathsim.utils.register ##### class Register This class is a intended to be used for the inputs and outputs of blocks. **Parameters:** - `size, default=None` — initial size of the register - `mapping, default=None` — string aliases for integer ports - `dtype, default=np.float64` **Register.__init__**`(size = None, mapping = None, dtype = np.float64)` - `size, default=None` - `mapping, default=None` - `dtype, default=np.float64` **Register.resize**`(size)` : Resize the internal data array to accommodate more entries. - `size` — new size for the internal data array **Register.reset**`()` : Set all stored values to zero. **Register.to_array**`()` : Returns a copy of the internal array. **Register.update_from_array**`(arr)` : Update the register values from an array in place. - `arr` — array or scalar that is used to update internal register values ### Examples #### [Harmonic Oscillator](https://docs.pathsim.org/pathsim/v0.19.0/examples/harmonic-oscillator) Simulation of a damped harmonic oscillator, modeling a spring-mass-damper system. Tags: ode, basics ```python import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Integrator, Amplifier, Adder, Scope # Initial position and velocity x0, v0 = 2, 5 # Parameters (mass, damping, spring constant) m, c, k = 0.8, 0.2, 1.5 # Blocks that define the system I1 = Integrator(v0) # integrator for velocity I2 = Integrator(x0) # integrator for position A1 = Amplifier(c) A2 = Amplifier(k) A3 = Amplifier(-1/m) P1 = Adder() Sc = Scope(labels=["velocity", "position"]) blocks = [I1, I2, A1, A2, A3, P1, Sc] # The connections between the blocks connections = [ Connection(I1, I2, A1, Sc), Connection(I2, A2, Sc[1]), Connection(A1, P1), Connection(A2, P1[1]), Connection(P1, A3), Connection(A3, I1) ] # Initialize simulation with the blocks, connections, timestep Sim = Simulation(blocks, connections, dt=0.01, log=True) # Run the simulation for 25 seconds Sim.run(duration=25) # Plot the results from the scope ``` #### [Linear Feedback System](https://docs.pathsim.org/pathsim/v0.19.0/examples/linear-feedback) Simulation of a simple linear feedback system with step response. Tags: ode, feedback ```python import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style for consistent, theme-friendly figures from pathsim import Simulation, Connection from pathsim.blocks import Source, Integrator, Amplifier, Adder, Scope # System parameters a, x0 = -1, 2 # Delay for step function tau = 3 # Step function def s(t): return int(t>tau) # Blocks that define the system Src = Source(s) Int = Integrator(x0) Amp = Amplifier(a) Add = Adder() Sco = Scope(labels=["step", "response"]) blocks = [Src, Int, Amp, Add, Sco] # The connections between the blocks connections = [ Connection(Src, Add[0], Sco[0]), Connection(Amp, Add[1]), Connection(Add, Int), Connection(Int, Amp, Sco[1]) ] # Initialize simulation with the blocks, connections, timestep Sim = Simulation(blocks, connections, dt=0.01, log=True) # Run the simulation for some time Sim.run(4*tau) # Read the data from the scope time, [data_step, data_response] = Sco.read() # Plot the results from the scope ``` #### [Pendulum](https://docs.pathsim.org/pathsim/v0.19.0/examples/pendulum) Simulation of a nonlinear mathematical pendulum. Tags: ode, adaptive, physics ```python import numpy as np import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style for consistent, theme-friendly figures from pathsim import Simulation, Connection from pathsim.blocks import (Integrator, Amplifier, Function, Adder, Scope) # Using an adaptive runge-kutta method from pathsim.solvers import RKCK54 # Initial angle and angular velocity phi0, omega0 = 0.9*np.pi, 0 # Parameters (gravity, length) g, l = 9.81, 1 # Blocks that define the system In1 = Integrator(omega0) In2 = Integrator(phi0) Amp = Amplifier(-g/l) Fnc = Function(np.sin) # <- function blocks just take callables Sco = Scope(labels=["angular velocity", "angle"]) blocks = [In1, In2, Amp, Fnc, Sco] # Connections between the blocks connections = [ Connection(In1, In2, Sco[0]), Connection(In2, Fnc, Sco[1]), Connection(Fnc, Amp), Connection(Amp, In1) ] # Simulation instance from the blocks and connections Sim = Simulation( blocks, connections, dt=0.1, Solver=RKCK54, tolerance_lte_rel=1e-6, tolerance_lte_abs=1e-8 ) # Run the simulation for 15 seconds Sim.run(duration=15) # Plot the results directly from the scope # Read the recordings from the scope time, *_ = Sco.read() ``` #### [Van der Pol](https://docs.pathsim.org/pathsim/v0.19.0/examples/vanderpol) Simulation of the Van der Pol oscillator, a classic example of a stiff dynamical system. Tags: ode, nonlinear #### [Anti-lock Braking System (ABS)](https://docs.pathsim.org/pathsim/v0.19.0/examples/abs-braking) This example demonstrates an anti-lock braking system (ABS) using nonlinear tire dynamics and event-driven slip control. The system prevents wheel lockup during braking by modulating brake torque t... Tags: hybrid, events, automotive #### [Cascade Controller](https://docs.pathsim.org/pathsim/v0.19.0/examples/cascade-controller) Demonstration of a two-loop cascade PID control system with inner and outer loops. Tags: cascade, feedback #### [DC Motor Speed Control](https://docs.pathsim.org/pathsim/v0.19.0/examples/dcmotor-control) This example demonstrates multi-domain modeling of a DC motor with PID speed control. The system combines electrical and mechanical dynamics with anti-windup control to handle voltage saturation. Tags: motor, pid #### [Kalman Filter](https://docs.pathsim.org/pathsim/v0.19.0/examples/kalman-filter) This example demonstrates the Kalman filter in PathSim for optimal state estimation of a linear dynamical system from noisy measurements. The filter recursively estimates the state of a moving obje... Tags: estimation, filter #### [PID Controller](https://docs.pathsim.org/pathsim/v0.19.0/examples/pid-controller) Simulation of a PID controller tracking a step-changing setpoint. Tags: pid, feedback #### [Thermostat](https://docs.pathsim.org/pathsim/v0.19.0/examples/thermostat) Simulation of a thermostat with threshold-based switching between heater states. Tags: hybrid, events #### [Billards & Collisions](https://docs.pathsim.org/pathsim/v0.19.0/examples/billards) Simulation of a ball bouncing inside a circular boundary using event detection. Tags: events, collision #### [Bouncing Ball](https://docs.pathsim.org/pathsim/v0.19.0/examples/bouncing-ball) Simulation of a bouncing ball using PathSim's event handling system. Tags: events, hybrid #### [Bouncing Pendulum](https://docs.pathsim.org/pathsim/v0.19.0/examples/bouncing-pendulum) This example demonstrates a hybrid system combining continuous pendulum dynamics with discrete bounce events. The pendulum swings until it hits the ground (zero angle), at which point it bounces ba... Tags: events, collision #### [Coupled Oscillators](https://docs.pathsim.org/pathsim/v0.19.0/examples/coupled-oscillators) Simulation of two coupled damped harmonic oscillators using ODE blocks. Tags: ode, physics #### [Elastic Pendulum](https://docs.pathsim.org/pathsim/v0.19.0/examples/elastic-pendulum) Simulation of an elastic pendulum combining spring and pendulum dynamics. Tags: ode, physics #### [Stick Slip](https://docs.pathsim.org/pathsim/v0.19.0/examples/stick-slip) Simulation of a mechanical system exhibiting stick-slip behavior due to Coulomb friction. Tags: friction, hybrid #### [Switched Bouncing Ball](https://docs.pathsim.org/pathsim/v0.19.0/examples/switched-bouncing-ball) This example demonstrates advanced event handling with multiple simultaneous events, event switching, and conditional event logic. The bouncing ball bounces on a table first, and then drops to the ... Tags: events, hybrid #### [Delta-Sigma ADC](https://docs.pathsim.org/pathsim/v0.19.0/examples/delta-sigma-adc) Simulation of a first-order delta-sigma analog-to-digital converter. Tags: adc, mixed-signal #### [Diode Circuit](https://docs.pathsim.org/pathsim/v0.19.0/examples/diode-circuit) Simulation of a diode circuit demonstrating nonlinear algebraic loop solving. Tags: nonlinear, circuit #### [Noisy Amplifier](https://docs.pathsim.org/pathsim/v0.19.0/examples/noisy-amplifier) Simulation of a nonlinear, noisy, and band-limited amplifier model. Tags: noise, circuit #### [SAR ADC](https://docs.pathsim.org/pathsim/v0.19.0/examples/sar-adc) Simulation of a Successive Approximation Register ADC with custom block creation. Tags: adc, mixed-signal #### [FMCW Radar](https://docs.pathsim.org/pathsim/v0.19.0/examples/fmcw-radar) In this example we simulate a simple frequency modulated continuous wave (FMCW) radar system. Tags: radar, frequency #### [RF Network - One Port](https://docs.pathsim.org/pathsim/v0.19.0/examples/rf-network-oneport) Simulation of a Radio Frequency (RF) network using scikit-rf for state-space conversion. Tags: rf, network #### [Spectrum Analysis](https://docs.pathsim.org/pathsim/v0.19.0/examples/spectrum-analysis) In this example we demonstrate frequency domain analysis using PathSim's spectrum block. We'll examine the frequency response of a Butterworth lowpass filter by analyzing its response to a Gaussian... Tags: fft, frequency #### [Transfer Function](https://docs.pathsim.org/pathsim/v0.19.0/examples/transfer-function) In this example we demonstrate how to use transfer functions in PathSim using the Pole-Residue-Constant (PRC) form. This representation is particularly convenient for transfer functions with comple... Tags: frequency, bode #### [Chemical Reactor](https://docs.pathsim.org/pathsim/v0.19.0/examples/chemical-reactor) Simulation of a continuous stirred tank reactor (CSTR) with consecutive exothermic reactions. Tags: cstr, reaction #### [Algebraic Loop](https://docs.pathsim.org/pathsim/v0.19.0/examples/algebraic-loop) Demonstration of PathSim's automatic handling of algebraic loops. Tags: algebraic, solver #### [Checkpoints](https://docs.pathsim.org/pathsim/v0.19.0/examples/checkpoints) PathSim supports saving and loading simulation state via checkpoints. This allows you to pause a simulation, save its complete state to disk, and resume it later from exactly where you left off. #### [Lorenz Attractor](https://docs.pathsim.org/pathsim/v0.19.0/examples/lorenz-attractor) Simulation of the famous Lorenz attractor, a chaotic dynamical system. Tags: chaos, ode #### [Nested Subsystems](https://docs.pathsim.org/pathsim/v0.19.0/examples/nested-subsystems) Demonstration of hierarchical modeling using nested subsystems for a Van der Pol oscillator. Tags: hierarchy, subsystem #### [Poincaré Maps](https://docs.pathsim.org/pathsim/v0.19.0/examples/poincare-maps) Demonstration of computing Poincaré sections for chaotic dynamical systems using event handling. Tags: analysis, chaos #### [FMU Co-Simulation](https://docs.pathsim.org/pathsim/v0.19.0/examples/fmu-cosimulation) Demonstration of integrating Functional Mock-up Units (FMU) as PathSim blocks. Tags: fmu, cosim #### [FMU ME: Bouncing Ball](https://docs.pathsim.org/pathsim/v0.19.0/examples/fmu-model-exchange-bouncing-ball) This example demonstrates Model Exchange FMU integration with PathSim. Unlike co-simulation FMUs, Model Exchange FMUs provide only the differential equations. PathSim's solvers perform the numerica... Tags: fmu, model-exchange #### [FMU ME: Van der Pol](https://docs.pathsim.org/pathsim/v0.19.0/examples/fmu-model-exchange-vanderpol) This example demonstrates Model Exchange FMU integration with a nonlinear oscillator. The Van der Pol equation exhibits self-sustained oscillations: Tags: fmu, model-exchange ## PathSim-Chem (v0.2.2) ### Quickstart From the [Activity Coefficients](https://docs.pathsim.org/chem/v0.2.2/examples/vle-calculation) example: ```python import matplotlib.pyplot as plt from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope, Function from pathsim_chem.thermodynamics import NRTL, Antoine # Temperature ramp from 330 K to 380 K src_t = Source(lambda t: 330 + t * 0.5) # Antoine vapor pressure correlations (ln form, T in K, P in Pa) antoine_ethanol = Antoine(a0=23.5807, a1=3673.81, a2=-46.681) antoine_water = Antoine(a0=23.2256, a1=3835.18, a2=-45.343) # NRTL activity coefficients for ethanol(1)-water(2) nrtl = NRTL( x=[0.4, 0.6], a=[[0, -0.801], [3.458, 0]], b=[[0, 200], [-100, 0]], c=[[0, 0.3], [0.3, 0]], ) # Compute bubble pressure from gamma and Psat values x1, x2 = 0.4, 0.6 bubble = Function(lambda g1, g2, P1, P2: x1 * g1 * P1 + x2 * g2 * P2) # Scopes to record activity coefficients and bubble pressure sco_gamma = Scope(labels=["gamma_ethanol", "gamma_water"]) sco_bubble = Scope(labels=["P_bubble"]) sim = Simulation( [src_t, nrtl, antoine_ethanol, antoine_water, bubble, sco_gamma, sco_bubble], [ Connection(src_t, nrtl, antoine_ethanol, antoine_water), Connection(nrtl, sco_gamma, bubble), Connection(nrtl[1], sco_gamma[1], bubble[1]), Connection(antoine_ethanol, bubble[2]), Connection(antoine_water, bubble[3]), Connection(bubble, sco_bubble), ], dt=0.5, log=True, ) sim.run(100) time, [gamma_eth, gamma_w] = sco_gamma.read() _, [P_bub] = sco_bubble.read() T_range = 330 + time * 0.5 ax1.plot(T_range - 273.15, gamma_eth, label=r"$\gamma_{\mathrm{ethanol}}$") ax1.plot(T_range - 273.15, gamma_w, label=r"$\gamma_{\mathrm{water}}$") ax1.axhline(1.0, color="gray", linestyle="--", alpha=0.5) ax1.set_xlabel("Temperature [°C]") ax1.set_ylabel(r"$\gamma_i$") ax1.set_title("NRTL Activity Coefficients") ax1.legend() ax1.grid(True, alpha=0.3) ax2.plot(T_range - 273.15, P_bub / 1e3) ax2.axhline(101.325, color="gray", linestyle="-.", alpha=0.5, label="1 atm") ax2.set_xlabel("Temperature [°C]") ax2.set_ylabel("Bubble Pressure [kPa]") ax2.set_title("Bubble Pressure (40/60 Ethanol-Water)") ax2.legend() ax2.grid(True, alpha=0.3) ``` ### API Reference #### pathsim_chem.neutronics.point_kinetics ##### class PointKinetics(pathsim.blocks.dynsys.DynamicalSystem) Reactor point kinetics equations with delayed neutron precursors. **Parameters:** - `n0, default=1.0` — Initial neutron density [-]. Default 1.0 (normalized). - `Lambda, default=1e-05` — Prompt neutron generation time [s]. - `beta, default=None` — Delayed neutron fractions per group [-]. - `lam, default=None` — Precursor decay constants per group [1/s]. **Attributes:** - `input_port_labels` - `output_port_labels` - `n0` - `Lambda` - `beta` - `lam` - `G` - `beta_total` **PointKinetics.__init__**`(n0 = 1.0, Lambda = 1e-05, beta = None, lam = None)` - `n0, default=1.0` - `Lambda, default=1e-05` - `beta, default=None` - `lam, default=None` #### pathsim_chem.process.cstr ##### class CSTR(pathsim.blocks.dynsys.DynamicalSystem) Continuous stirred-tank reactor with Arrhenius kinetics and energy balance. **Parameters:** - `V, default=1.0` — Reactor volume [m³]. - `F, default=0.1` — Volumetric flow rate [m³/s]. - `k0, default=1000000.0` — Pre-exponential Arrhenius factor [1/s for n=1, (m³/mol)^(n-1)/s]. - `Ea, default=50000.0` — Activation energy [J/mol]. - `n, default=1.0` — Reaction order with respect to species A [-]. - `dH_rxn, default=-50000.0` — Heat of reaction [J/mol]. Negative for exothermic reactions. - `rho, default=1000.0` — Fluid density [kg/m³]. - `Cp, default=4184.0` — Fluid heat capacity [J/(kg·K)]. - `UA, default=500.0` — Overall heat transfer coefficient times area [W/K]. - `C_A0, default=0.0` — Initial concentration of A [mol/m³]. - `T0, default=300.0` — Initial reactor temperature [K]. **Attributes:** - `input_port_labels` - `output_port_labels` - `V` - `F` - `k0` - `Ea` - `n` - `dH_rxn` - `rho` - `Cp` - `UA` **CSTR.__init__**`(V = 1.0, F = 0.1, k0 = 1000000.0, Ea = 50000.0, n = 1.0, dH_rxn = -50000.0, rho = 1000.0, Cp = 4184.0, UA = 500.0, C_A0 = 0.0, T0 = 300.0)` - `V, default=1.0` - `F, default=0.1` - `k0, default=1000000.0` - `Ea, default=50000.0` - `n, default=1.0` - `dH_rxn, default=-50000.0` - `rho, default=1000.0` - `Cp, default=4184.0` - `UA, default=500.0` - `C_A0, default=0.0` - `T0, default=300.0` #### pathsim_chem.process.distillation ##### class DistillationTray(pathsim.blocks.dynsys.DynamicalSystem) Single equilibrium distillation tray with constant molar overflow. **Parameters:** - `M, default=1.0` — Liquid holdup on the tray [mol]. - `alpha, default=2.5` — Relative volatility of light to heavy component [-]. - `x0, default=0.5` — Initial liquid mole fraction of light component [-]. **Attributes:** - `input_port_labels` - `output_port_labels` - `M` - `alpha` **DistillationTray.__init__**`(M = 1.0, alpha = 2.5, x0 = 0.5)` - `M, default=1.0` - `alpha, default=2.5` - `x0, default=0.5` #### pathsim_chem.process.flash_drum ##### class FlashDrum(pathsim.blocks.dynsys.DynamicalSystem) Binary isothermal flash drum with Raoult's law vapor-liquid equilibrium. **Parameters:** - `holdup, default=100.0` — Total liquid holdup [mol]. Assumed approximately constant. - `antoine_A, default=None` — Antoine A parameters for each component [ln(Pa)]. - `antoine_B, default=None` — Antoine B parameters for each component [K]. - `antoine_C, default=None` — Antoine C parameters for each component [K]. - `N0, default=None` — Initial component holdup moles [mol]. If None, equal split assumed. **Attributes:** - `input_port_labels` - `output_port_labels` - `holdup` - `antoine_A` - `antoine_B` - `antoine_C` **FlashDrum.__init__**`(holdup = 100.0, antoine_A = None, antoine_B = None, antoine_C = None, N0 = None)` - `holdup, default=100.0` - `antoine_A, default=None` - `antoine_B, default=None` - `antoine_C, default=None` - `N0, default=None` #### pathsim_chem.process.heat_exchanger ##### class HeatExchanger(pathsim.blocks.dynsys.DynamicalSystem) Counter-current shell and tube heat exchanger with discretized cells. **Parameters:** - `N_cells, default=5` — Number of discretization cells along the exchanger [-]. - `F_h, default=0.1` — Hot stream volumetric flow rate [m³/s]. - `F_c, default=0.1` — Cold stream volumetric flow rate [m³/s]. - `V_h, default=0.5` — Total hot-side volume [m³]. - `V_c, default=0.5` — Total cold-side volume [m³]. - `UA, default=500.0` — Total overall heat transfer coefficient times area [W/K]. - `rho_h, default=1000.0` — Hot stream density [kg/m³]. - `Cp_h, default=4184.0` — Hot stream heat capacity [J/(kg·K)]. - `rho_c, default=1000.0` — Cold stream density [kg/m³]. - `Cp_c, default=4184.0` — Cold stream heat capacity [J/(kg·K)]. - `T_h0, default=370.0` — Initial hot-side temperature [K]. - `T_c0, default=300.0` — Initial cold-side temperature [K]. **Attributes:** - `input_port_labels` - `output_port_labels` - `N_cells` - `F_h` - `F_c` - `V_h` - `V_c` - `UA` - `rho_h` - `Cp_h` - `rho_c` - `Cp_c` **HeatExchanger.__init__**`(N_cells = 5, F_h = 0.1, F_c = 0.1, V_h = 0.5, V_c = 0.5, UA = 500.0, rho_h = 1000.0, Cp_h = 4184.0, rho_c = 1000.0, Cp_c = 4184.0, T_h0 = 370.0, T_c0 = 300.0)` - `N_cells, default=5` - `F_h, default=0.1` - `F_c, default=0.1` - `V_h, default=0.5` - `V_c, default=0.5` - `UA, default=500.0` - `rho_h, default=1000.0` - `Cp_h, default=4184.0` - `rho_c, default=1000.0` - `Cp_c, default=4184.0` - `T_h0, default=370.0` - `T_c0, default=300.0` #### pathsim_chem.process.heater ##### class Heater(pathsim.blocks.function.Function) Algebraic duty-specified heater/cooler with no thermal mass. **Parameters:** - `rho, default=1000.0` — Fluid density [kg/m³]. - `Cp, default=4184.0` — Fluid heat capacity [J/(kg·K)]. **Attributes:** - `input_port_labels` - `output_port_labels` - `rho` - `Cp` **Heater.__init__**`(rho = 1000.0, Cp = 4184.0)` - `rho, default=1000.0` - `Cp, default=4184.0` #### pathsim_chem.process.mixer ##### class Mixer(pathsim.blocks.function.Function) Algebraic 2-stream mixer with mass and energy balance. **Attributes:** - `input_port_labels` - `output_port_labels` **Mixer.__init__**`()` #### pathsim_chem.process.multicomponent_flash ##### class MultiComponentFlash(pathsim.blocks.dynsys.DynamicalSystem) Generalized isothermal flash drum for N components with Raoult's law VLE. **Parameters:** - `N_comp, default=3` — Number of components (must be >= 2). - `holdup, default=100.0` — Total liquid holdup [mol]. Assumed approximately constant. - `antoine_A, default=None` — Antoine A parameters for each component [ln(Pa)]. - `antoine_B, default=None` — Antoine B parameters for each component [K]. - `antoine_C, default=None` — Antoine C parameters for each component [K]. - `N0, default=None` — Initial component holdup moles [mol]. If None, equal split assumed. **Attributes:** - `N_comp` - `holdup` - `antoine_A` - `antoine_B` - `antoine_C` - `input_port_labels` - `output_port_labels` **MultiComponentFlash.__init__**`(N_comp = 3, holdup = 100.0, antoine_A = None, antoine_B = None, antoine_C = None, N0 = None)` - `N_comp, default=3` - `holdup, default=100.0` - `antoine_A, default=None` - `antoine_B, default=None` - `antoine_C, default=None` - `N0, default=None` #### pathsim_chem.process.pfr ##### class PFR(pathsim.blocks.dynsys.DynamicalSystem) Plug flow reactor with Arrhenius kinetics and energy balance. **Parameters:** - `N_cells, default=5` — Number of discretization cells [-]. - `V, default=1.0` — Total reactor volume [m³]. - `F, default=0.1` — Volumetric flow rate [m³/s]. - `k0, default=1000000.0` — Pre-exponential Arrhenius factor [1/s for n=1]. - `Ea, default=50000.0` — Activation energy [J/mol]. - `n, default=1.0` — Reaction order [-]. - `dH_rxn, default=-50000.0` — Heat of reaction [J/mol]. Negative for exothermic. - `rho, default=1000.0` — Fluid density [kg/m³]. - `Cp, default=4184.0` — Fluid heat capacity [J/(kg·K)]. - `C0, default=0.0` — Initial concentration [mol/m³]. - `T0, default=300.0` — Initial temperature [K]. **Attributes:** - `input_port_labels` - `output_port_labels` - `N_cells` - `V` - `F` - `k0` - `Ea` - `n` - `dH_rxn` - `rho` - `Cp` **PFR.__init__**`(N_cells = 5, V = 1.0, F = 0.1, k0 = 1000000.0, Ea = 50000.0, n = 1.0, dH_rxn = -50000.0, rho = 1000.0, Cp = 4184.0, C0 = 0.0, T0 = 300.0)` - `N_cells, default=5` - `V, default=1.0` - `F, default=0.1` - `k0, default=1000000.0` - `Ea, default=50000.0` - `n, default=1.0` - `dH_rxn, default=-50000.0` - `rho, default=1000.0` - `Cp, default=4184.0` - `C0, default=0.0` - `T0, default=300.0` #### pathsim_chem.process.valve ##### class Valve(pathsim.blocks.function.Function) Algebraic pressure-drop valve with standard flow equation. **Parameters:** - `Cv, default=1.0` — Valve flow coefficient. Must be positive. **Attributes:** - `input_port_labels` - `output_port_labels` - `Cv` **Valve.__init__**`(Cv = 1.0)` - `Cv, default=1.0` #### pathsim_chem.thermodynamics.activity_coefficients ##### class NRTL(pathsim.blocks.function.Function) Non-Random Two-Liquid activity coefficient model (IK-CAPE Chapter 4.1). **Parameters:** - `x` — Mole fractions [N]. Fixed mixture composition. - `a` — Constant part of the energy interaction parameter :math:`\tau` [N x N]. Diagonal elements should be zero. For constant (temperature-independent) tau values, set ``a=tau`` and leave ``b``, ``e``, ``f`` as zero. - `b, default=None` — Coefficient of :math:`1/T` in :math:`\tau_{ji}` [N x N]. Default: zeros. - `c, default=None` — Constant part of the non-randomness parameter :math:`\alpha` [N x N]. - `d, default=None` — Temperature-dependent part of :math:`\alpha` [N x N]. Default: zeros. - `e, default=None` — G_{ji} = \exp(-\alpha_{ji} \, \tau_{ji}) - `f, default=None` — Coefficient of :math:`T` in :math:`\tau_{ji}` [N x N]. Default: zeros. **Attributes:** - `input_port_labels` - `x` - `n` - `a` - `b` - `e` - `f` - `c` - `d` **NRTL.__init__**`(x, a, b = None, c = None, d = None, e = None, f = None)` - `x` - `a` - `b, default=None` - `c, default=None` - `d, default=None` - `e, default=None` - `f, default=None` ##### class Wilson(pathsim.blocks.function.Function) Wilson activity coefficient model (IK-CAPE Chapter 4.3). **Parameters:** - `x` — Mole fractions [N]. Fixed mixture composition. - `a` — Constant part of :math:`\ln \Lambda_{ij}` [N x N]. Diagonal should be zero so that :math:`\Lambda_{ii} = 1`. - `b, default=None` — Coefficient of :math:`1/T` in :math:`\ln \Lambda_{ij}` [N x N]. - `c, default=None` — Coefficient of :math:`\ln T` in :math:`\ln \Lambda_{ij}` [N x N]. - `d, default=None` — Coefficient of :math:`T` in :math:`\ln \Lambda_{ij}` [N x N]. **Attributes:** - `input_port_labels` - `x` - `n` - `a` - `b` - `c` - `d` **Wilson.__init__**`(x, a, b = None, c = None, d = None)` - `x` - `a` - `b, default=None` - `c, default=None` - `d, default=None` ##### class UNIQUAC(pathsim.blocks.function.Function) Universal Quasi-Chemical activity coefficient model (IK-CAPE Chapter 4.2). **Parameters:** - `x` — Mole fractions [N]. Fixed mixture composition. - `r` — Van der Waals volume (size) parameters [N], from UNIFAC tables or fitted to data. Example: ethanol=2.1055, water=0.92. - `q` — Van der Waals surface area parameters [N]. Example: ethanol=1.972, water=1.4. - `a` — Constant part of the interaction parameter exponent [N x N]. Diagonal should be zero. The interaction parameter is computed as :math:`\tau_{ji} = \exp(a_{ji} + b_{ji}/T + c_{ji} \ln T + d_{ji} T)`. - `q_prime, default=None` — Modified surface area for the residual part [N]. Used in some formulations (e.g., for water/alcohol systems). Defaults to ``q``. - `b, default=None` — Coefficient of :math:`1/T` in the :math:`\tau` exponent [N x N]. - `c, default=None` — Coefficient of :math:`\ln T` in the :math:`\tau` exponent [N x N]. - `d, default=None` — Coefficient of :math:`T` in the :math:`\tau` exponent [N x N]. - `z, default=10` — Lattice coordination number (default 10, the standard value). **Attributes:** - `input_port_labels` - `x` - `n` - `r` - `q` - `q_prime` - `z` - `a` - `b_param` - `c_param` - `d_param` - `l` **UNIQUAC.__init__**`(x, r, q, a, q_prime = None, b = None, c = None, d = None, z = 10)` - `x` - `r` - `q` - `a` - `q_prime, default=None` - `b, default=None` - `c, default=None` - `d, default=None` - `z, default=10` ##### class FloryHuggins(pathsim.blocks.function.Function) Flory-Huggins activity coefficient model (IK-CAPE Chapter 4.4). **Parameters:** - `x` — Mole fractions [N] where ``x[0]`` is the solvent and ``x[1:]`` are the polymer species. - `r` — .. math:: - `chi0` — Constant part of the Flory-Huggins interaction parameter [N-1]. - `chi1, default=None` — Temperature-dependent part of :math:`\chi` [N-1]. Default: zeros. **Attributes:** - `input_port_labels` - `x` - `n` - `r_poly` - `chi0` - `chi1` **FloryHuggins.__init__**`(x, r, chi0, chi1 = None)` - `x` - `r` - `chi0` - `chi1, default=None` #### pathsim_chem.thermodynamics.averages ##### class MolarAverage(pathsim.blocks.function.Function) Molar average mixing rule (IK-CAPE code: MOLA). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `x` **MolarAverage.__init__**`(x)` - `x` ##### class MassAverage(pathsim.blocks.function.Function) Mass fraction average mixing rule (IK-CAPE code: MASS). **Parameters:** - `w` — Mass fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `w` **MassAverage.__init__**`(w)` - `w` ##### class LogMolarAverage(pathsim.blocks.function.Function) Logarithmic molar average mixing rule (IK-CAPE code: MOLG). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `x` **LogMolarAverage.__init__**`(x)` - `x` ##### class LogMassAverage(pathsim.blocks.function.Function) Logarithmic mass fraction average mixing rule (IK-CAPE code: MALG). **Parameters:** - `w` — Mass fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `w` **LogMassAverage.__init__**`(w)` - `w` ##### class LambdaAverage(pathsim.blocks.function.Function) Thermal conductivity average for gaseous mixtures (IK-CAPE code: LAMB). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `x` **LambdaAverage.__init__**`(x)` - `x` ##### class ViscosityAverage(pathsim.blocks.function.Function) Viscosity average for gaseous mixtures (IK-CAPE code: VISC). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. - `M` — Molecular weights [kg/kmol] for each component. **Attributes:** - `output_port_labels` - `x` - `M` - `weights` **ViscosityAverage.__init__**`(x, M)` - `x` - `M` ##### class VolumeAverage(pathsim.blocks.function.Function) Volume-based density average (IK-CAPE code: VOLU). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. **Attributes:** - `output_port_labels` - `x` **VolumeAverage.__init__**`(x)` - `x` ##### class WilkeViscosity(pathsim.blocks.function.Function) Wilke mixing rule for gas viscosity (IK-CAPE code: WILK). **Parameters:** - `y` — Mole fractions (vapor phase) for each component. - `M` — Molecular weights [kg/kmol] for each component. **Attributes:** - `output_port_labels` - `y` - `M` **WilkeViscosity.__init__**`(y, M)` - `y` - `M` ##### class WassiljewaMasonSaxena(pathsim.blocks.function.Function) Wassiljewa-Mason-Saxena mixing rule for gas thermal conductivity **Parameters:** - `y` — Mole fractions (vapor phase) for each component. - `M` — Molecular weights [kg/kmol] for each component. **Attributes:** - `output_port_labels` - `y` - `M` - `n` **WassiljewaMasonSaxena.__init__**`(y, M)` - `y` - `M` ##### class DIPPRSurfaceTension(pathsim.blocks.function.Function) DIPPR surface tension average (IK-CAPE code: DIST). **Parameters:** - `x` — Mole fractions for each component. Determines the number of input ports. - `V` — Molar volumes [m^3/kmol] for each component. **Attributes:** - `output_port_labels` - `x` - `V` - `xV` **DIPPRSurfaceTension.__init__**`(x, V)` - `x` - `V` ##### class DIPPRLiquidConductivity(pathsim.blocks.function.Function) DIPPR liquid thermal conductivity average (IK-CAPE code: DIKL). **Parameters:** - `x` — Mole fractions for each component. - `V` — Molar volumes [m^3/kmol] for each component. **Attributes:** - `output_port_labels` - `x` - `V` - `xv` **DIPPRLiquidConductivity.__init__**`(x, V)` - `x` - `V` #### pathsim_chem.thermodynamics.corrections ##### class PoyntingCorrection(pathsim.blocks.function.Function) Poynting pressure correction factor (IK-CAPE Chapter 5). **Attributes:** - `input_port_labels` - `output_port_labels` **PoyntingCorrection.__init__**`()` ##### class HenryConstant(pathsim.blocks.function.Function) Temperature-dependent Henry's law constant (IK-CAPE Chapter 6). **Parameters:** - `a` — Constant term in :math:`\ln H`. - `b, default=0.0` — Coefficient of :math:`1/T`. Controls the temperature sensitivity (related to enthalpy of dissolution). Default: 0. - `c, default=0.0` — Coefficient of :math:`\ln T`. Default: 0. - `d, default=0.0` — p_i = H_{i,j} \, x_i **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **HenryConstant.__init__**`(a, b = 0.0, c = 0.0, d = 0.0)` - `a` - `b, default=0.0` - `c, default=0.0` - `d, default=0.0` #### pathsim_chem.thermodynamics.correlations ##### class Polynomial(pathsim.blocks.function.Function) Polynomial correlation (IK-CAPE code: POLY). **Parameters:** - `coeffs` — Polynomial coefficients :math:`[a_0, a_1, \ldots, a_n]` (up to 10). **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Polynomial.__init__**`(coeffs)` - `coeffs` ##### class ExponentialPolynomial(pathsim.blocks.function.Function) Exponential polynomial correlation (IK-CAPE code: EPOL). **Parameters:** - `coeffs` — Polynomial exponent coefficients :math:`[a_0, a_1, \ldots, a_n]` (up to 10). **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **ExponentialPolynomial.__init__**`(coeffs)` - `coeffs` ##### class Watson(pathsim.blocks.function.Function) Watson correlation (IK-CAPE code: WATS). **Parameters:** - `a0` - `a1` - `a2` - `a3, default=0.0` — Watson correlation coefficients. :math:`a_2` is typically the critical temperature. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Watson.__init__**`(a0, a1, a2, a3 = 0.0)` - `a0` - `a1` - `a2` - `a3, default=0.0` ##### class Antoine(pathsim.blocks.function.Function) Antoine correlation (IK-CAPE code: ANTO). **Parameters:** - `a0` - `a1` - `a2` — Antoine coefficients. For natural-log form with T in Kelvin. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Antoine.__init__**`(a0, a1, a2)` - `a0` - `a1` - `a2` ##### class ExtendedAntoine(pathsim.blocks.function.Function) Extended Antoine correlation (IK-CAPE code: ANT1). **Parameters:** - `a0` - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` - `a6, default=0.0` — Extended Antoine coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **ExtendedAntoine.__init__**`(a0, a1, a2, a3 = 0.0, a4 = 0.0, a5 = 0.0, a6 = 0.0)` - `a0` - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` - `a6, default=0.0` ##### class Kirchhoff(pathsim.blocks.function.Function) Kirchhoff correlation (IK-CAPE code: KIRC). **Parameters:** - `a0` - `a1` - `a2` — Kirchhoff coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Kirchhoff.__init__**`(a0, a1, a2)` - `a0` - `a1` - `a2` ##### class ExtendedKirchhoff(pathsim.blocks.function.Function) Extended Kirchhoff correlation (IK-CAPE code: KIR1). **Parameters:** - `a0` - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` — Extended Kirchhoff coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **ExtendedKirchhoff.__init__**`(a0, a1, a2, a3 = 0.0, a4 = 0.0)` - `a0` - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` ##### class Sutherland(pathsim.blocks.function.Function) Sutherland correlation (IK-CAPE code: SUTH). **Parameters:** - `a0` - `a1` — Sutherland coefficients. :math:`a_1` is the Sutherland constant. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Sutherland.__init__**`(a0, a1)` - `a0` - `a1` ##### class Wagner(pathsim.blocks.function.Function) Wagner correlation (IK-CAPE code: WAGN). **Parameters:** - `Tc` — Critical temperature :math:`a_0` [K]. - `Pc` — Critical pressure :math:`a_1` [Pa]. a2, a3, a4, a5 : float Wagner correlation coefficients. - `a2` - `a3` - `a4` - `a5` — Wagner correlation coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Wagner.__init__**`(Tc, Pc, a2, a3, a4, a5)` - `Tc` - `Pc` - `a2` - `a3` - `a4` - `a5` ##### class LiquidHeatCapacity(pathsim.blocks.function.Function) Liquid heat capacity correlation (IK-CAPE code: CPL). **Parameters:** - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` - `a4, default=0.0` — Liquid Cp coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **LiquidHeatCapacity.__init__**`(a0, a1 = 0.0, a2 = 0.0, a3 = 0.0, a4 = 0.0)` - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` - `a4, default=0.0` ##### class ExtendedLiquidHeatCapacity(pathsim.blocks.function.Function) Extended liquid heat capacity correlation (IK-CAPE code: ICPL). **Parameters:** - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` — Extended liquid Cp coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **ExtendedLiquidHeatCapacity.__init__**`(a0, a1 = 0.0, a2 = 0.0, a3 = 0.0, a4 = 0.0, a5 = 0.0)` - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` ##### class DynamicViscosity(pathsim.blocks.function.Function) Dynamic viscosity correlation (IK-CAPE code: VISC). **Parameters:** - `a0` - `a1` — Pre-exponential factor and activation energy parameter. - `a2, default=0.0` — Additive constant (default 0). **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **DynamicViscosity.__init__**`(a0, a1, a2 = 0.0)` - `a0` - `a1` - `a2, default=0.0` ##### class Rackett(pathsim.blocks.function.Function) Rackett correlation (IK-CAPE code: RACK). **Parameters:** - `a0` — Scaling parameter (related to critical volume). - `a1` — Rackett parameter (base of exponent). - `a2` — Critical temperature [K]. - `a3` — Exponent parameter (often 2/7). **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **Rackett.__init__**`(a0, a1, a2, a3)` - `a0` - `a1` - `a2` - `a3` ##### class AlyLee(pathsim.blocks.function.Function) Aly-Lee correlation (IK-CAPE code: ALYL). **Parameters:** - `a0` - `a1` - `a2` - `a3` - `a4` — Aly-Lee coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **AlyLee.__init__**`(a0, a1, a2, a3, a4)` - `a0` - `a1` - `a2` - `a3` - `a4` ##### class DIPPR4(pathsim.blocks.function.Function) DIPPR Equation 4 correlation (IK-CAPE code: DIP4). **Parameters:** - `Tc` — Critical temperature :math:`a_0` [K]. a1, a2, a3, a4, a5 : float DIPPR-4 coefficients. - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` — DIPPR-4 coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **DIPPR4.__init__**`(Tc, a1, a2, a3 = 0.0, a4 = 0.0, a5 = 0.0)` - `Tc` - `a1` - `a2` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` ##### class DIPPR5(pathsim.blocks.function.Function) DIPPR Equation 5 correlation (IK-CAPE code: DIP5). **Parameters:** - `a0` - `a1` - `a2, default=0.0` - `a3, default=0.0` — DIPPR-5 coefficients. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **DIPPR5.__init__**`(a0, a1, a2 = 0.0, a3 = 0.0)` - `a0` - `a1` - `a2, default=0.0` - `a3, default=0.0` #### pathsim_chem.thermodynamics.enthalpy ##### class ExcessEnthalpyNRTL(pathsim.blocks.function.Function) Excess enthalpy from the NRTL model (IK-CAPE Chapter 9.6.1). **Parameters:** - `x` — Mole fractions [N]. Fixed mixture composition. - `a` — Constant part of :math:`\tau` [N x N]. Diagonal should be zero. - `b, default=None` — Coefficient of :math:`1/T` in :math:`\tau` [N x N]. Default: zeros. - `c, default=None` — Constant part of non-randomness :math:`\alpha` [N x N]. - `d, default=None` — Temperature-dependent part of :math:`\alpha` [N x N]. Default: zeros. - `e, default=None` — A_i = \sum_j x_j G_{j,i} \tau_{j,i}, \quad A'_i = \sum_j x_j (G'_{j,i} \tau_{j,i} + G_{j,i} \tau'_{j,i}) - `f, default=None` — Coefficient of :math:`T` in :math:`\tau` [N x N]. Default: zeros. **Attributes:** - `input_port_labels` - `output_port_labels` - `x` - `n` - `a` - `b` - `e` - `f` - `c` - `d` **ExcessEnthalpyNRTL.__init__**`(x, a, b = None, c = None, d = None, e = None, f = None)` - `x` - `a` - `b, default=None` - `c, default=None` - `d, default=None` - `e, default=None` - `f, default=None` ##### class ExcessEnthalpyUNIQUAC(pathsim.blocks.function.Function) Excess enthalpy from the UNIQUAC model (IK-CAPE Chapter 9.6.2). **Parameters:** - `x` — Mole fractions [N]. - `r` — Van der Waals volume parameters [N]. - `q` — Van der Waals surface area parameters [N]. - `a` — Constant part of the :math:`\\tau` exponent [N x N]. - `q_prime, default=None` — Modified surface area for residual part [N]. Defaults to ``q``. - `b, default=None` — Coefficient of :math:`1/T` [N x N]. Default: zeros. - `c, default=None` — Coefficient of :math:`\\ln T` [N x N]. Default: zeros. - `d, default=None` — **Input port:** ``T`` -- temperature [K]. **Attributes:** - `input_port_labels` - `output_port_labels` - `x` - `n` - `r` - `q` - `q_prime` - `a` - `b_param` - `c_param` - `d_param` **ExcessEnthalpyUNIQUAC.__init__**`(x, r, q, a, q_prime = None, b = None, c = None, d = None)` - `x` - `r` - `q` - `a` - `q_prime, default=None` - `b, default=None` - `c, default=None` - `d, default=None` ##### class ExcessEnthalpyWilson(pathsim.blocks.function.Function) Excess enthalpy from the Wilson model (IK-CAPE Chapter 9.6.3). **Parameters:** - `x` — Mole fractions [N]. - `a` — Constant part of :math:`\ln \Lambda_{ij}` [N x N]. - `b, default=None` — Coefficient of :math:`1/T` [N x N]. Default: zeros. - `c, default=None` — Coefficient of :math:`\ln T` [N x N]. Default: zeros. - `d, default=None` — .. math:: **Attributes:** - `input_port_labels` - `output_port_labels` - `x` - `n` - `a` - `b` - `c` - `d` **ExcessEnthalpyWilson.__init__**`(x, a, b = None, c = None, d = None)` - `x` - `a` - `b, default=None` - `c, default=None` - `d, default=None` ##### class ExcessEnthalpyRedlichKister(pathsim.blocks.function.Function) Excess enthalpy from the Redlich-Kister expansion (IK-CAPE Chapter 9.6.5). **Parameters:** - `x` — Mole fractions [N]. - `coeffs` — Redlich-Kister coefficients keyed by binary pair ``(i, j)`` as tuples. Each value is a list of polynomial coefficient arrays, one per Redlich-Kister term. Example for a single pair (0,1) with 3 terms:: **Attributes:** - `input_port_labels` - `output_port_labels` - `x` - `n` - `coeffs` **ExcessEnthalpyRedlichKister.__init__**`(x, coeffs)` - `x` - `coeffs` ##### class EnthalpyDepartureRKS(pathsim.blocks.function.Function) Isothermal enthalpy departure from the SRK EoS (IK-CAPE Chapter 9.7.1). **Parameters:** - `Tc` — Critical temperature(s) [K]. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. - `x, default=None` — Mole fractions [N]. Required for mixtures. - `k, default=None` — Binary interaction parameters [N x N]. Default: zeros. - `phase, default='vapor'` — ``"vapor"`` (default) or ``"liquid"``. **Attributes:** - `input_port_labels` - `output_port_labels` - `Tc` - `Pc` - `omega` - `nc` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **EnthalpyDepartureRKS.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` ##### class EnthalpyDeparturePR(pathsim.blocks.function.Function) Isothermal enthalpy departure from the Peng-Robinson EoS (IK-CAPE Chapter 9.7.2). **Parameters:** - `Tc` — Critical temperature(s) [K]. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. - `x, default=None` — Mole fractions [N]. Required for mixtures. - `k, default=None` — Binary interaction parameters [N x N]. Default: zeros. - `phase, default='vapor'` — ``"vapor"`` (default) or ``"liquid"``. **Attributes:** - `input_port_labels` - `output_port_labels` - `Tc` - `Pc` - `omega` - `nc` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **EnthalpyDeparturePR.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` #### pathsim_chem.thermodynamics.equations_of_state ##### class PengRobinson(pathsim.blocks.function.Function) Peng-Robinson cubic equation of state (IK-CAPE Chapter 7.2). **Parameters:** - `Tc` — Critical temperature(s) [K]. Scalar for pure component, array for mixture. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. Characterizes deviation from spherical symmetry. Available in standard reference tables (e.g., DIPPR). - `x, default=None` — Mole fractions [N]. Required for mixtures, omit for pure components. - `k, default=None` — Binary interaction parameters [N x N]. Symmetric, with :math:`k_{ii} = 0`. Default: zero for all pairs. - `phase, default='vapor'` — Phase root selection: ``"vapor"`` (default) picks the largest Z root, ``"liquid"`` picks the smallest positive Z root. **Attributes:** - `input_port_labels` - `output_port_labels` - `Tc` - `Pc` - `omega` - `n` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **PengRobinson.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` ##### class RedlichKwongSoave(pathsim.blocks.function.Function) Soave-Redlich-Kwong cubic equation of state (IK-CAPE Chapter 7.1). **Parameters:** - `Tc` — Critical temperature(s) [K]. Scalar for pure component, array for mixture. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. - `x, default=None` — Mole fractions [N]. Required for mixtures, omit for pure components. - `k, default=None` — Binary interaction parameters [N x N]. Default: zero for all pairs. - `phase, default='vapor'` — Phase root selection: ``"vapor"`` (default) or ``"liquid"``. **Attributes:** - `input_port_labels` - `output_port_labels` - `Tc` - `Pc` - `omega` - `n` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **RedlichKwongSoave.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` ##### _solve_cubic_eos`(coeffs, phase = 'vapor')` Solve cubic equation in Z and return the appropriate root. #### pathsim_chem.thermodynamics.fugacity_coefficients ##### class FugacityRKS(pathsim.blocks.function.Function) Fugacity coefficients from the Soave-Redlich-Kwong EoS (IK-CAPE Chapter 8.1). **Parameters:** - `Tc` — Critical temperature(s) [K]. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. - `x, default=None` — Mole fractions [N]. Required for mixtures, omit for pure components. - `k, default=None` — Binary interaction parameters [N x N]. Default: zero for all pairs. - `phase, default='vapor'` — ``"vapor"`` (default) or ``"liquid"`` -- selects the EoS root. **Attributes:** - `input_port_labels` - `Tc` - `Pc` - `omega` - `nc` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **FugacityRKS.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` ##### class FugacityPR(pathsim.blocks.function.Function) Fugacity coefficients from the Peng-Robinson EoS (IK-CAPE Chapter 8.2). **Parameters:** - `Tc` — Critical temperature(s) [K]. - `Pc` — Critical pressure(s) [Pa]. - `omega` — Acentric factor(s) [-]. - `x, default=None` — Mole fractions [N]. Required for mixtures, omit for pure components. - `k, default=None` — Binary interaction parameters [N x N]. Default: zero for all pairs. - `phase, default='vapor'` — ``"vapor"`` (default) or ``"liquid"`` -- selects the EoS root. **Attributes:** - `input_port_labels` - `Tc` - `Pc` - `omega` - `nc` - `phase` - `x` - `k` - `m` - `a_c` - `b_i` **FugacityPR.__init__**`(Tc, Pc, omega, x = None, k = None, phase = 'vapor')` - `Tc` - `Pc` - `omega` - `x, default=None` - `k, default=None` - `phase, default='vapor'` ##### class FugacityVirial(pathsim.blocks.function.Function) Fugacity coefficients from the truncated virial equation (IK-CAPE Chapter 8.3). **Parameters:** - `B` — Second virial coefficients [N x N] in [m^3/mol]. For a pure component, pass a scalar or 1x1 array. For a mixture, pass the full symmetric matrix including cross-coefficients :math:`B_{ij}`. These are typically functions of temperature, but here assumed constant at the evaluation temperature. - `y, default=None` — Vapor-phase mole fractions [N]. Required for mixtures. **Attributes:** - `input_port_labels` - `B` - `nc` - `y` **FugacityVirial.__init__**`(B, y = None)` - `B` - `y, default=None` #### pathsim_chem.thermodynamics.reactions ##### class EquilibriumConstant(pathsim.blocks.function.Function) Temperature-dependent chemical equilibrium constant (IK-CAPE Chapter 10.1). **Parameters:** - `a0` — Constant term. - `a1, default=0.0` — Coefficient of :math:`1/T`. Related to the standard enthalpy of reaction. Default: 0. - `a2, default=0.0` — Coefficient of :math:`\ln T`. Related to heat capacity change. - `a3, default=0.0` — Coefficient of :math:`T`. Default: 0. - `a4, default=0.0` — Coefficient of :math:`T^2`. Default: 0. - `a5, default=0.0` — Coefficient of :math:`T^3`. Default: 0. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **EquilibriumConstant.__init__**`(a0, a1 = 0.0, a2 = 0.0, a3 = 0.0, a4 = 0.0, a5 = 0.0)` - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` - `a4, default=0.0` - `a5, default=0.0` ##### class KineticRateConstant(pathsim.blocks.function.Function) Temperature-dependent kinetic rate constant (IK-CAPE Chapter 10.2). **Parameters:** - `a0` — Constant term (:math:`\ln A` for Arrhenius). - `a1, default=0.0` — Coefficient of :math:`1/T` (:math:`-E_a/R`). Default: 0. - `a2, default=0.0` — Coefficient of :math:`\ln T` (power-law temperature exponent). - `a3, default=0.0` — Coefficient of :math:`T`. Default: 0. **Attributes:** - `input_port_labels` - `output_port_labels` - `coeffs` **KineticRateConstant.__init__**`(a0, a1 = 0.0, a2 = 0.0, a3 = 0.0)` - `a0` - `a1, default=0.0` - `a2, default=0.0` - `a3, default=0.0` ##### class PowerLawRate(pathsim.blocks.function.Function) Power-law reaction rate expression (IK-CAPE Chapter 10.2 KILM/KIVM). **Parameters:** - `nu` — Stoichiometric coefficient matrix [N_c x N_r]. Negative for reactants, positive for products. - `nu_fwd, default=None` — Forward reaction orders [N_c x N_r]. If not given, the absolute values of the negative stoichiometric coefficients are used (i.e., elementary reaction kinetics). - `Keq, default=None` — Equilibrium constants [N_r]. If provided, an equilibrium driving force term is included. Default: None (irreversible reactions). **Attributes:** - `nu` - `nu_fwd` - `Keq` **PowerLawRate.__init__**`(nu, nu_fwd = None, Keq = None)` - `nu` - `nu_fwd, default=None` - `Keq, default=None` #### pathsim_chem.tritium.bubbler ##### class Bubbler4(pathsim.blocks.dynsys.DynamicalSystem) Tritium bubbling system with sequential vial collection stages. **Parameters:** - `conversion_efficiency, default=0.9` — Conversion efficiency from insoluble to soluble forms (:math:`\alpha_{conv}`), between 0 and 1. - `vial_efficiency, default=0.9` — Collection efficiency of each vial (:math:`\eta_{vial}`), between 0 and 1. - `replacement_times, default=None` — Times at which each vial is replaced with a fresh one. If None, no replacement events are created. If a single value is provided, it is used for all vials. If a single list of floats is provided, it will be used for all vials. If a list of lists is provided, each sublist corresponds to the replacement times for each vial. **Attributes:** - `input_port_labels` - `output_port_labels` - `replacement_times` - `vial_efficiency` - `conversion_efficiency` **Bubbler4.__init__**`(conversion_efficiency = 0.9, vial_efficiency = 0.9, replacement_times = None)` - `conversion_efficiency, default=0.9` - `vial_efficiency, default=0.9` - `replacement_times, default=None` #### pathsim_chem.tritium.glc ##### class GLC(pathsim.blocks.Function) Counter-current bubble column gas-liquid contactor (GLC) for tritium extraction. **Parameters:** - `P_in` — Inlet operating pressure [Pa]. - `L` — Column height [m]. - `D` — Column diameter [m]. - `T` — Operating temperature [K]. Used to compute temperature-dependent LiPb properties (density, viscosity, Sieverts' constant, etc.). - `BCs` — Boundary condition type for the BVP: ``"C-C"`` (closed-closed) or ``"O-C"`` (open-closed). - `g, default=const.g` — Gravitational acceleration [m/s²]. Default: ``scipy.constants.g``. - `initial_nb_of_elements, default=20` — Number of mesh elements for the initial BVP grid. Default: 20. **Attributes:** - `input_port_labels` - `output_port_labels` - `params` **GLC.__init__**`(P_in, L, D, T, BCs, g = const.g, initial_nb_of_elements = 20)` - `P_in` - `L` - `D` - `T` - `BCs` - `g, default=const.g` - `initial_nb_of_elements, default=20` **GLC.func**`(c_T_in, flow_l, y_T2_inlet, flow_g)` - `c_T_in` - `flow_l` - `y_T2_inlet` - `flow_g` ##### _calculate_properties`(params)` Calculate temperature-dependent and geometry-dependent physical properties. ##### _calculate_dimensionless_groups`(params, phys_props)` Calculate the dimensionless groups for the ODE system. ##### _solve_bvp_system`(dim_params, y_T2_in, BCs, elements)` Set up and solve the Boundary Value Problem for tritium extraction. ##### _process_results`(solution, params, phys_props, dim_params)` Process the BVP solution to produce dimensional results. ##### solve`(params)` Main solver function for the bubble column model. #### pathsim_chem.tritium.residencetime ##### class ResidenceTime(pathsim.blocks.dynsys.DynamicalSystem) Chemical process block with residence time model. **Parameters:** - `tau, default=1` — residence time, inverse natural frequency (eigenvalue) - `betas, default=None` — weights of inputs that are accumulated in state, optional - `gammas, default=None` — weights of states (fractions) for output, optional - `initial_value, default=0` — initial value of state / initial quantity of process - `source_term, default=0` — constant source term / generation term of the process **Attributes:** - `tau` - `betas` - `gammas` - `source_term` **ResidenceTime.__init__**`(tau = 1, betas = None, gammas = None, initial_value = 0, source_term = 0)` - `tau, default=1` - `betas, default=None` - `gammas, default=None` - `initial_value, default=0` - `source_term, default=0` ##### class Process(pathsim_chem.tritium.residencetime.ResidenceTime) Simplified version of the `ResidenceTime` model block **Parameters:** - `tau, default=1` — residence time, inverse natural frequency (eigenvalue) - `initial_value, default=0` — initial value of state / initial quantity of process - `source_term, default=0` — constant source term / generation term of the process **Attributes:** - `input_port_labels` - `output_port_labels` **Process.__init__**`(tau = 1, initial_value = 0, source_term = 0)` - `tau, default=1` - `initial_value, default=0` - `source_term, default=0` #### pathsim_chem.tritium.splitter ##### class Splitter(pathsim.blocks.function.Function) Splitter block that splits the input signal into multiple **Parameters:** - `fractions, default=None` — fractions to split the input signal into, must sum up to one **Attributes:** - `input_port_labels` - `output_port_labels` - `fractions` **Splitter.__init__**`(fractions = None)` - `fractions, default=None` #### pathsim_chem.tritium.tcap ##### class TCAP1D(pathsim.blocks.ode.ODE) This block models the Thermal Cycle Absorption Process (TCAP) in 1d. ### Examples #### [Activity Coefficients](https://docs.pathsim.org/chem/v0.2.2/examples/vle-calculation) Simulating how NRTL activity coefficients for the ethanol-water system evolve with temperature using PathSim blocks and connections. Tags: thermodynamics, vle ```python import matplotlib.pyplot as plt from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope, Function from pathsim_chem.thermodynamics import NRTL, Antoine # Temperature ramp from 330 K to 380 K src_t = Source(lambda t: 330 + t * 0.5) # Antoine vapor pressure correlations (ln form, T in K, P in Pa) antoine_ethanol = Antoine(a0=23.5807, a1=3673.81, a2=-46.681) antoine_water = Antoine(a0=23.2256, a1=3835.18, a2=-45.343) # NRTL activity coefficients for ethanol(1)-water(2) nrtl = NRTL( x=[0.4, 0.6], a=[[0, -0.801], [3.458, 0]], b=[[0, 200], [-100, 0]], c=[[0, 0.3], [0.3, 0]], ) # Compute bubble pressure from gamma and Psat values x1, x2 = 0.4, 0.6 bubble = Function(lambda g1, g2, P1, P2: x1 * g1 * P1 + x2 * g2 * P2) # Scopes to record activity coefficients and bubble pressure sco_gamma = Scope(labels=["gamma_ethanol", "gamma_water"]) sco_bubble = Scope(labels=["P_bubble"]) sim = Simulation( [src_t, nrtl, antoine_ethanol, antoine_water, bubble, sco_gamma, sco_bubble], [ Connection(src_t, nrtl, antoine_ethanol, antoine_water), Connection(nrtl, sco_gamma, bubble), Connection(nrtl[1], sco_gamma[1], bubble[1]), Connection(antoine_ethanol, bubble[2]), Connection(antoine_water, bubble[3]), Connection(bubble, sco_bubble), ], dt=0.5, log=True, ) sim.run(100) time, [gamma_eth, gamma_w] = sco_gamma.read() _, [P_bub] = sco_bubble.read() T_range = 330 + time * 0.5 ax1.plot(T_range - 273.15, gamma_eth, label=r"$\gamma_{\mathrm{ethanol}}$") ax1.plot(T_range - 273.15, gamma_w, label=r"$\gamma_{\mathrm{water}}$") ax1.axhline(1.0, color="gray", linestyle="--", alpha=0.5) ax1.set_xlabel("Temperature [°C]") ax1.set_ylabel(r"$\gamma_i$") ax1.set_title("NRTL Activity Coefficients") ax1.legend() ax1.grid(True, alpha=0.3) ax2.plot(T_range - 273.15, P_bub / 1e3) ax2.axhline(101.325, color="gray", linestyle="-.", alpha=0.5, label="1 atm") ax2.set_xlabel("Temperature [°C]") ax2.set_ylabel("Bubble Pressure [kPa]") ax2.set_title("Bubble Pressure (40/60 Ethanol-Water)") ax2.legend() ax2.grid(True, alpha=0.3) ``` #### [Continuous Stirred-Tank Reactor](https://docs.pathsim.org/chem/v0.2.2/examples/cstr-reaction) Simulating the startup transient of an exothermic first-order reaction in a cooled CSTR, showing the dynamic interaction between concentration decay and temperature rise. Tags: cstr, reaction, dynamics ```python import matplotlib.pyplot as plt from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope from pathsim_chem.process import CSTR reactor = CSTR( V=1.0, # reactor volume [m³] F=0.05, # volumetric flow rate [m³/s] -> tau = 20 s k0=1e6, # pre-exponential factor [1/s] Ea=40000.0, # activation energy [J/mol] n=1.0, # first-order reaction dH_rxn=-40000.0, # exothermic [J/mol] rho=1000.0, # density [kg/m³] Cp=4184.0, # heat capacity [J/(kg·K)] UA=800.0, # cooling jacket [W/K] C_A0=0.0, # start empty T0=300.0, # initial temperature [K] ) # Constant feed and coolant conditions src_c = Source(lambda t: 1000.0) # feed concentration [mol/m³] src_t = Source(lambda t: 320.0) # feed temperature [K] src_tc = Source(lambda t: 290.0) # coolant temperature [K] sco = Scope(labels=["C_A [mol/m³]", "T [K]"]) sim = Simulation( [src_c, src_t, src_tc, reactor, sco], [ Connection(src_c, reactor), # C_in Connection(src_t, reactor[1]), # T_in Connection(src_tc, reactor[2]), # T_c Connection(reactor, sco), # C_out Connection(reactor[1], sco[1]), # T_out ], dt=0.1, log=True, ) sim.run(200) sco.plot(lw=1.5) ``` #### [Counter-Current Heat Exchanger](https://docs.pathsim.org/chem/v0.2.2/examples/heat-exchanger) Simulating the startup transient of a counter-current shell-and-tube heat exchanger, showing how temperature profiles develop along the exchanger length. Tags: heat-transfer, dynamics ```python import numpy as np import matplotlib.pyplot as plt from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope from pathsim_chem.process import HeatExchanger hx = HeatExchanger( N_cells=10, # spatial discretization F_h=0.002, # hot flow rate [m³/s] F_c=0.002, # cold flow rate [m³/s] V_h=0.1, # hot-side volume [m³] V_c=0.1, # cold-side volume [m³] UA=5000.0, # overall heat transfer [W/K] rho_h=1000.0, # hot-side density [kg/m³] Cp_h=4184.0, # hot-side heat capacity [J/(kg·K)] rho_c=1000.0, # cold-side density [kg/m³] Cp_c=4184.0, # cold-side heat capacity [J/(kg·K)] T_h0=300.0, # initial hot-side temp [K] T_c0=300.0, # initial cold-side temp [K] ) src_th = Source(lambda t: 370.0) # hot inlet [K] src_tc = Source(lambda t: 290.0) # cold inlet [K] sco = Scope(labels=["T_h_out [K]", "T_c_out [K]"]) sim = Simulation( [src_th, src_tc, hx, sco], [ Connection(src_th, hx), # T_h_in Connection(src_tc, hx[1]), # T_c_in Connection(hx, sco), # T_h_out Connection(hx[1], sco[1]), # T_c_out ], dt=0.02, log=True, ) sim.run(200) sco.plot(lw=1.5) ``` #### [Cubic Equations of State](https://docs.pathsim.org/chem/v0.2.2/examples/equation-of-state) Simulating the compressibility factor of methane across a pressure sweep using the Peng-Robinson and Soave-Redlich-Kwong equations of state wired into a PathSim simulation. Tags: thermodynamics, eos #### [Flash Drum and Distillation Column](https://docs.pathsim.org/chem/v0.2.2/examples/flash-distillation) Simulating two fundamental separation processes: an isothermal binary flash drum and a multi-tray distillation column built from individual blocks wired in series. Tags: separation, vle, distillation #### [Vapor Pressure Curves](https://docs.pathsim.org/chem/v0.2.2/examples/vapor-pressure-curves) Comparing vapor pressure correlations for water by sweeping temperature through Antoine, Kirchhoff, and Wagner blocks wired into a PathSim simulation. Tags: thermodynamics, vle #### [Multi-Component Flash Separation (BTX)](https://docs.pathsim.org/chem/v0.2.2/examples/multicomponent-flash) Simulating an isothermal flash drum for a ternary benzene–toluene–p-xylene (BTX) mixture. #### [Process Flowsheet: Mixer → Heater → CSTR](https://docs.pathsim.org/chem/v0.2.2/examples/process-flowsheet) A simple process combining multiple unit operations into a flowsheet: #### [Reactor Point Kinetics](https://docs.pathsim.org/chem/v0.2.2/examples/point-kinetics) Simulating the transient neutron population in a nuclear reactor using the point kinetics equations (PKE) with six delayed neutron precursor groups. #### [Valve Flow Characteristics](https://docs.pathsim.org/chem/v0.2.2/examples/valve-characteristics) Exploring the flow behaviour of the block under varying pressure drop conditions. ## PathSim-Flight (v0.1.0) ### API Reference #### pathsim_flight.atmosphere.international_standard_atmosphere ##### class ISAtmosphere(pathsim.blocks.Function) International Standard Atmosphere. **Attributes:** - `input_port_labels` - `output_port_labels` - `R` - `g0` - `gamma` - `r0` - `StdSL_pressure` - `StdSL_speed_of_sound` - `AtmosphereBand` - `atmosphere_bands` **ISAtmosphere.__init__**`()` **ISAtmosphere.geopotential_altitude**`(geometric_altitude)` - `geometric_altitude` **ISAtmosphere.geometric_altitude**`(geopotential_altitude)` - `geopotential_altitude` **ISAtmosphere.get_atmosphere_band**`(geopot_altitude)` - `geopot_altitude` #### pathsim_flight.jsbsim.jsbsim_wrapper ##### class JSBSimWrapper(pathsim.blocks.Wrapper) A wrapper for the JSBSim flight dynamics model, which allows it to be **Parameters:** - `T, default=1 / 120` — The time step for the JSBSim model, in seconds. Default is 1/120, which corresponds to 120 Hz. - `input_properties, default=None` — A list of JSBSim property names that correspond to the input ports of the block. - `output_properties, default=None` — A list of JSBSim property names that correspond to the output ports of the block. - `JSBSim_path, default=None` — The file path to the JSBSim installation. If None, it will look for JSBSim files in the pip install location. - `aircraft_model, default='737'` — The name of the aircraft model to load in JSBSim. Default is '737'. - `trim_airspeed, default=200` — The airspeed to use for trimming the aircraft, as KCAS. Default is 200 KCAS. - `trim_altitude, default=1000` — The altitude ASL to use for trimming the aircraft, in feet. Default is 1000 ft ASL. - `trim_gamma, default=0` — The flight path angle to use for trimming the aircraft, in degrees. Default is 0 degrees (level flight). **Attributes:** - `input_port_labels` - `output_port_labels` - `input_properties` - `output_properties` **JSBSimWrapper.__init__**`(T = 1 / 120, input_properties = None, output_properties = None, JSBSim_path = None, aircraft_model = '737', trim_airspeed = 200, trim_altitude = 1000, trim_gamma = 0)` - `T, default=1 / 120` - `input_properties, default=None` - `output_properties, default=None` - `JSBSim_path, default=None` - `aircraft_model, default='737'` - `trim_airspeed, default=200` - `trim_altitude, default=1000` - `trim_gamma, default=0` **JSBSimWrapper.init_fdm**`(JSBSim_path, aircraft_model, T)` - `JSBSim_path` - `aircraft_model` - `T` **JSBSimWrapper.trim**`(trim_airspeed, trim_alitude, trim_gamma)` - `trim_airspeed` - `trim_alitude` - `trim_gamma` #### pathsim_flight.utils.airspeed_conversions ##### class CAStoMach(pathsim.blocks.Function) Convert calibrated airspeed (CAS) to Mach value. **Attributes:** - `input_port_labels` - `output_port_labels` **CAStoMach.__init__**`()` ##### class CAStoTAS(pathsim.blocks.Function) Convert calibrated airspeed (CAS) to true airspeed (TAS). **Attributes:** - `input_port_labels` - `output_port_labels` **CAStoTAS.__init__**`()` ##### class TAStoCAS(pathsim.blocks.Function) Convert true airspeed (TAS) to calibrated airspeed (CAS). **Attributes:** - `input_port_labels` - `output_port_labels` **TAStoCAS.__init__**`()` ##### class CAStoEAS(pathsim.blocks.Function) Convert calibrated airspeed (CAS) to equivalent airspeed (EAS). **Attributes:** - `input_port_labels` - `output_port_labels` **CAStoEAS.__init__**`()` ##### class EAStoTAS(pathsim.blocks.Function) Convert equivalent airspeed (EAS) to true airspeed (TAS). **Attributes:** - `input_port_labels` - `output_port_labels` **EAStoTAS.__init__**`()` ##### class MachtoCAS(pathsim.blocks.Function) Convert Mach value to calibrated airspeed (CAS). **Attributes:** - `input_port_labels` - `output_port_labels` **MachtoCAS.__init__**`()` ## PathSim-RF (v0.1.1) ### Quickstart From the [RF Amplifier Compression](https://docs.pathsim.org/rf/v0.1.1/examples/rf-amplifier-compression) example: ```python import numpy as np import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope from pathsim.solvers import RKCK54 from pathsim_rf import RFAmplifier # Amplifier parameters gain_dB = 20.0 # Small-signal gain [dB] IIP3_dBm = 10.0 # Input-referred IP3 [dBm] Z0 = 50.0 # Reference impedance [Ohm] f0 = 100.0 # Signal frequency [Hz] (scaled for simulation) # Linear regime: -20 dBm input p_watts = 10.0 ** (-20.0 / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) src = Source(func=lambda t: v_peak * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope(labels=['input', 'output']) sim = Simulation( [src, amp, sco], [Connection(src, amp, sco[0]), Connection(amp, sco[1])], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(3 / f0) # Compressed regime: +5 dBm input p_watts = 10.0 ** (5.0 / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) src = Source(func=lambda t: v_peak * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope(labels=['input', 'output']) sim = Simulation( [src, amp, sco], [Connection(src, amp, sco[0]), Connection(amp, sco[1])], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(3 / f0) # Sweep input power levels pin_dbm = np.arange(-30, 15, 1.0) pout_dbm = np.zeros_like(pin_dbm) for i, p_in in enumerate(pin_dbm): # Input amplitude from power in dBm p_watts = 10.0 ** (p_in / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) # Build simulation src = Source(func=lambda t, vp=v_peak: vp * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope() sim = Simulation( [src, amp, sco], [Connection(src, amp), Connection(amp, sco)], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(10 / f0) # Read output and measure peak amplitude (last half) t, [y] = sco.read() n_last = int(len(t) * 0.5) v_out_peak = np.max(np.abs(y[n_last:])) # Convert to output power in dBm p_out = v_out_peak ** 2 / (2 * Z0) pout_dbm[i] = 10 * np.log10(p_out / 1e-3) if p_out > 0 else -100 p1db_in = IIP3_dBm - 9.6 ``` ### API Reference #### pathsim_rf.amplifier ##### class RFAmplifier(pathsim.blocks.function.Function) RF amplifier with optional nonlinearity (IP3 / P1dB compression). **Parameters:** - `gain, default=20.0` — Small-signal voltage gain [dB]. Default 20.0. - `P1dB, default=None` — Input-referred 1 dB compression point [dBm]. If given without *IIP3*, the intercept is estimated as IIP3 = P1dB + 9.6 dB. - `IIP3, default=None` — Input-referred third-order intercept point [dBm]. Takes precedence over *P1dB* if both are given. - `Z0, default=50.0` — Reference impedance [Ohm]. Default 50.0. **Attributes:** - `input_port_labels` - `output_port_labels` - `gain` - `Z0` - `IIP3` - `P1dB` **RFAmplifier.__init__**`(gain = 20.0, P1dB = None, IIP3 = None, Z0 = 50.0)` - `gain, default=20.0` - `P1dB, default=None` - `IIP3, default=None` - `Z0, default=50.0` ##### _dbm_to_vpeak`(p_dbm, z0)` Convert power in dBm to peak voltage amplitude. #### pathsim_rf.mixer ##### class RFMixer(pathsim.blocks.function.Function) Ideal RF mixer (frequency converter). **Parameters:** - `conversion_gain, default=0.0` — Conversion gain [dB]. Default 0.0. Negative values represent conversion loss (typical for passive mixers). - `Z0, default=50.0` — Reference impedance [Ohm]. Default 50.0. **Attributes:** - `input_port_labels` - `output_port_labels` - `conversion_gain` - `Z0` **RFMixer.__init__**`(conversion_gain = 0.0, Z0 = 50.0)` - `conversion_gain, default=0.0` - `Z0, default=50.0` #### pathsim_rf.network ##### class RFNetwork(pathsim.blocks.lti.StateSpace) N-port RF network linear time invariant (LTI) MIMO state-space model. **Parameters:** - `ntwk (rf.Network | str | Path)` — scikit-rf RF Network object, or file to load information from. Supported formats are touchstone file V1 (.s?p) or V2 (.ts). - `auto_fit (bool), default=True` — If True (default), use ``skrf.VectorFitting.auto_fit`` for automatic pole selection. If False, use ``skrf.VectorFitting.vector_fit``. **kwargs Additional keyword arguments forwarded to the vector fitting function. - `kwargs, default={}` **Attributes:** - `network` - `vf` **RFNetwork.__init__**`(ntwk: rf.Network | str | Path, auto_fit: bool = True, kwargs = {})` - `ntwk` - `auto_fit, default=True` - `kwargs, default={}` **RFNetwork.s**`(freqs: np.ndarray)` : S-matrix of the vector fitted N-port model from its state-space representation. - `freqs` — Frequencies (in Hz) at which to calculate the S-matrices. #### pathsim_rf.transmission_line ##### class TransmissionLine(pathsim.blocks._block.Block) Lossy transmission line modeled as a delayed scattering two-port. **Parameters:** - `length, default=1.0` — Physical length of the line [m]. - `er, default=1.0` — Effective relative permittivity [-]. Default 1.0 (free space). - `attenuation, default=0.0` — b_1(t) = T \cdot a_2(t - \tau) - `Z0, default=50.0` — Characteristic impedance [Ohm]. Stored for reference, does not affect the scattering computation (matched-line assumption). **Attributes:** - `input_port_labels` - `output_port_labels` - `length` - `er` - `attenuation` - `Z0` - `vp` - `tau` - `T` **TransmissionLine.__init__**`(length = 1.0, er = 1.0, attenuation = 0.0, Z0 = 50.0)` - `length, default=1.0` - `er, default=1.0` - `attenuation, default=0.0` - `Z0, default=50.0` **TransmissionLine.reset**`()` **TransmissionLine.sample**`(t, dt)` : Store current incident waves into the delay buffer. - `t` - `dt` **TransmissionLine.update**`(t)` : Read delayed waves, cross and scale. - `t` ### Examples #### [RF Amplifier Compression](https://docs.pathsim.org/rf/v0.1.1/examples/rf-amplifier-compression) Simulation of an RF amplifier with gain compression demonstrating the third-order nonlinearity model. We sweep the input power and observe the 1 dB compression point and gain saturation behavior. Tags: amplifier, nonlinear, compression ```python import numpy as np import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope from pathsim.solvers import RKCK54 from pathsim_rf import RFAmplifier # Amplifier parameters gain_dB = 20.0 # Small-signal gain [dB] IIP3_dBm = 10.0 # Input-referred IP3 [dBm] Z0 = 50.0 # Reference impedance [Ohm] f0 = 100.0 # Signal frequency [Hz] (scaled for simulation) # Linear regime: -20 dBm input p_watts = 10.0 ** (-20.0 / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) src = Source(func=lambda t: v_peak * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope(labels=['input', 'output']) sim = Simulation( [src, amp, sco], [Connection(src, amp, sco[0]), Connection(amp, sco[1])], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(3 / f0) # Compressed regime: +5 dBm input p_watts = 10.0 ** (5.0 / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) src = Source(func=lambda t: v_peak * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope(labels=['input', 'output']) sim = Simulation( [src, amp, sco], [Connection(src, amp, sco[0]), Connection(amp, sco[1])], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(3 / f0) # Sweep input power levels pin_dbm = np.arange(-30, 15, 1.0) pout_dbm = np.zeros_like(pin_dbm) for i, p_in in enumerate(pin_dbm): # Input amplitude from power in dBm p_watts = 10.0 ** (p_in / 10.0) * 1e-3 v_peak = np.sqrt(2.0 * Z0 * p_watts) # Build simulation src = Source(func=lambda t, vp=v_peak: vp * np.sin(2 * np.pi * f0 * t)) amp = RFAmplifier(gain=gain_dB, IIP3=IIP3_dBm, Z0=Z0) sco = Scope() sim = Simulation( [src, amp, sco], [Connection(src, amp), Connection(amp, sco)], dt=1 / (40 * f0), Solver=RKCK54 ) sim.run(10 / f0) # Read output and measure peak amplitude (last half) t, [y] = sco.read() n_last = int(len(t) * 0.5) v_out_peak = np.max(np.abs(y[n_last:])) # Convert to output power in dBm p_out = v_out_peak ** 2 / (2 * Z0) pout_dbm[i] = 10 * np.log10(p_out / 1e-3) if p_out > 0 else -100 p1db_in = IIP3_dBm - 9.6 ``` #### [RF Mixer Downconversion](https://docs.pathsim.org/rf/v0.1.1/examples/rf-mixer-downconversion) Simulation of a superheterodyne downconversion stage using the block. A high-frequency RF signal is mixed with a local oscillator (LO) to produce an intermediate frequency (IF) output. Tags: mixer, frequency, downconversion ```python import numpy as np import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope, Spectrum from pathsim.solvers import RKCK54 from pathsim_rf import RFMixer # Frequencies f_rf = 1000.0 # RF signal frequency [Hz] f_lo = 900.0 # Local oscillator frequency [Hz] f_if = f_rf - f_lo # Expected IF frequency [Hz] # Simulation timestep (must resolve highest frequency) dt = 1 / (20 * (f_rf + f_lo)) duration = 10 / f_if # Run for 10 IF cycles # Build blocks rf_src = Source(func=lambda t: np.sin(2 * np.pi * f_rf * t)) lo_src = Source(func=lambda t: np.sin(2 * np.pi * f_lo * t)) mixer = RFMixer(conversion_gain=0.0) # Observe time and frequency domain sco = Scope(labels=['RF', 'LO', 'IF']) freq = np.linspace(0, 2500, 500) spc = Spectrum(freq=freq, labels=['IF']) connections = [ Connection(rf_src, mixer[0], sco[0]), Connection(lo_src, mixer[1], sco[1]), Connection(mixer, sco[2], spc), ] sim = Simulation( [rf_src, lo_src, mixer, sco, spc], connections, dt=dt, Solver=RKCK54, tolerance_lte_rel=1e-5, tolerance_lte_abs=1e-7 ) sim.run(duration) sco.plot() spc.plot() ``` #### [Superheterodyne Receiver Chain](https://docs.pathsim.org/rf/v0.1.1/examples/superheterodyne-receiver) Simulation of a basic superheterodyne receiver front-end combining multiple PathSim-RF blocks: an RF amplifier (LNA), a mixer for downconversion, and an IF amplifier. This demonstrates how the bloc... Tags: receiver, system ```python import numpy as np import matplotlib.pyplot as plt # Apply PathSim docs matplotlib style from pathsim import Simulation, Connection from pathsim.blocks import Source, Scope, Spectrum from pathsim.solvers import RKCK54 from pathsim_rf import RFAmplifier, RFMixer # Signal frequencies f_rf = 1000.0 f_lo = 900.0 f_if = f_rf - f_lo # Input signal (weak RF signal) Z0 = 50.0 p_in_dbm = -30.0 # -30 dBm input p_watts = 10.0 ** (p_in_dbm / 10.0) * 1e-3 v_rf = np.sqrt(2.0 * Z0 * p_watts) # LO amplitude (strong local oscillator) v_lo = 1.0 # 1V peak # Build signal chain rf_src = Source(func=lambda t: v_rf * np.sin(2 * np.pi * f_rf * t)) lo_src = Source(func=lambda t: v_lo * np.sin(2 * np.pi * f_lo * t)) lna = RFAmplifier(gain=15.0, IIP3=5.0, Z0=Z0) mixer = RFMixer(conversion_gain=0.0, Z0=Z0) if_amp = RFAmplifier(gain=20.0, IIP3=15.0, Z0=Z0) # Observation points at each stage sco = Scope(labels=['RF input', 'LNA output', 'IF output']) # Spectrum at output freq = np.linspace(0, 2500, 500) spc = Spectrum(freq=freq, labels=['IF output']) connections = [ Connection(rf_src, lna, sco[0]), Connection(lo_src, mixer[1]), Connection(lna, mixer[0], sco[1]), Connection(mixer, if_amp), Connection(if_amp, sco[2], spc), ] sim = Simulation( [rf_src, lo_src, lna, mixer, if_amp, sco, spc], connections, dt=1 / (20 * (f_rf + f_lo)), Solver=RKCK54, tolerance_lte_rel=1e-5, tolerance_lte_abs=1e-7 ) sim.run(20 / f_if) sco.plot() spc.plot() ``` #### [Transmission Line Pulse Propagation](https://docs.pathsim.org/rf/v0.1.1/examples/transmission-line-reflection) Simulation of pulse propagation through a lossy transmission line using the block. We observe the propagation delay and attenuation of a Gaussian pulse traveling through the line. Tags: transmission-line, propagation ## Links - [PathSim Homepage](https://pathsim.org): Project homepage - [PathView Editor](https://view.pathsim.org): Browser-based visual block diagram editor - [PathSim Codegen](https://code.pathsim.org): Generate C99 code from PathSim models - [GitHub](https://github.com/pathsim): Source code repositories - [PyPI](https://pypi.org/project/pathsim): Python package - [JOSS Paper](https://doi.org/10.21105/joss.07484): Published paper