pathsim 0.21.1__tar.gz → 0.22.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. {pathsim-0.21.1 → pathsim-0.22.1}/.github/workflows/pypi_deployment.yml +2 -2
  2. {pathsim-0.21.1 → pathsim-0.22.1}/.github/workflows/tests_codecov.yml +2 -2
  3. {pathsim-0.21.1 → pathsim-0.22.1}/.github/workflows/urlchecker.yml +1 -1
  4. {pathsim-0.21.1 → pathsim-0.22.1}/PKG-INFO +1 -1
  5. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/__init__.py +1 -0
  6. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/_version.py +3 -3
  7. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/_block.py +30 -1
  8. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/connection.py +24 -0
  9. pathsim-0.22.1/src/pathsim/exceptions.py +44 -0
  10. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/simulation.py +36 -15
  11. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim.egg-info/PKG-INFO +1 -1
  12. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim.egg-info/SOURCES.txt +1 -0
  13. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_block.py +27 -0
  14. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/test_connection.py +57 -1
  15. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/test_simulation.py +141 -3
  16. {pathsim-0.21.1 → pathsim-0.22.1}/.codecov.yml +0 -0
  17. {pathsim-0.21.1 → pathsim-0.22.1}/.github/FUNDING.yml +0 -0
  18. {pathsim-0.21.1 → pathsim-0.22.1}/.gitignore +0 -0
  19. {pathsim-0.21.1 → pathsim-0.22.1}/CITATION.cff +0 -0
  20. {pathsim-0.21.1 → pathsim-0.22.1}/LICENSE.txt +0 -0
  21. {pathsim-0.21.1 → pathsim-0.22.1}/README.md +0 -0
  22. {pathsim-0.21.1 → pathsim-0.22.1}/conftest.py +0 -0
  23. {pathsim-0.21.1 → pathsim-0.22.1}/docs/.readthedocs.yaml +0 -0
  24. {pathsim-0.21.1 → pathsim-0.22.1}/docs/Makefile +0 -0
  25. {pathsim-0.21.1 → pathsim-0.22.1}/docs/requirements.txt +0 -0
  26. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/_ext/github_issues.py +0 -0
  27. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/_static/custom.css +0 -0
  28. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/_static/redirect.js +0 -0
  29. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/api.rst +0 -0
  30. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/conf.py +0 -0
  31. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/contributing.rst +0 -0
  32. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/abs_braking.ipynb +0 -0
  33. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/algebraic_loop.ipynb +0 -0
  34. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/billards.ipynb +0 -0
  35. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/bouncing_ball.ipynb +0 -0
  36. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/bouncing_pendulum.ipynb +0 -0
  37. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/cascade_controller.ipynb +0 -0
  38. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/checkpoints.ipynb +0 -0
  39. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/chemical_reactor.ipynb +0 -0
  40. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/coupled_oscillators.ipynb +0 -0
  41. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/data/BouncingBall_ME.fmu +0 -0
  42. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/data/CoupledClutches_CS_linux64.fmu +0 -0
  43. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/data/CoupledClutches_CS_win64.fmu +0 -0
  44. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/data/Dahlquist.fmu +0 -0
  45. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/data/VanDerPol_ME.fmu +0 -0
  46. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/dcmotor_control.ipynb +0 -0
  47. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/delta_sigma_adc.ipynb +0 -0
  48. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/diode_circuit.ipynb +0 -0
  49. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/elastic_pendulum.ipynb +0 -0
  50. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/algebraicloop_blockdiagram_g.png +0 -0
  51. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/billard_circle_g.png +0 -0
  52. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_blockdiagram_g.png +0 -0
  53. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_both_g.png +0 -0
  54. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_g.png +0 -0
  55. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_result_events_g.png +0 -0
  56. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_result_g.png +0 -0
  57. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_ball_result_timesteps_g.png +0 -0
  58. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/bouncing_pendulum_blockdiagram_g.png +0 -0
  59. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/cascade_blockdiagram_g.png +0 -0
  60. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/coupled_oscillators_blockdiagram_g.png +0 -0
  61. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/coupled_oscillators_g.png +0 -0
  62. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/delta_sigma_blockdiagram_g.png +0 -0
  63. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/diode_blockdiagram_g.png +0 -0
  64. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/elastic_pendulum_g.png +0 -0
  65. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/fmcw_blockdiagram_g.png +0 -0
  66. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/fmcw_g.png +0 -0
  67. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/harmonic_oscillator_g.png +0 -0
  68. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/harmonic_oscillator_result_g.png +0 -0
  69. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/kalman_filter_blockdiagram_g.png +0 -0
  70. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/linear_feedback_blockdiagram_g.png +0 -0
  71. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/linear_feedback_result_g.png +0 -0
  72. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/linear_feedback_result_sensitivity_g.png +0 -0
  73. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/miller_frequency_divider_blockdiagram_g.png +0 -0
  74. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/nonlinear_noisy_amplifier_blockdiagram_g.png +0 -0
  75. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/ode_blockdiagram_g.png +0 -0
  76. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/pendulum_blockdiagram_g.png +0 -0
  77. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/pid_blockdiagram_g.png +0 -0
  78. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/sar_adc_blockdiagram_g.png +0 -0
  79. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_g.png +0 -0
  80. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_slip_g.png +0 -0
  81. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_stick_g.png +0 -0
  82. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/stick_slip_g.png +0 -0
  83. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/thermostat_blockdiagram_g.png +0 -0
  84. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_blockdiagram_g.png +0 -0
  85. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_result_g.png +0 -0
  86. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_subsystem_blockdiagram_g.png +0 -0
  87. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl1_g.png +0 -0
  88. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl2_g.png +0 -0
  89. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl3_g.png +0 -0
  90. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/figures_g/volterralotka_blockdiagram_g.png +0 -0
  91. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/ode_blockdiagram_2.png +0 -0
  92. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/stick_slip_blockdiagram_slip.png +0 -0
  93. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/figures/stick_slip_blockdiagram_stick.png +0 -0
  94. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/fmcw_radar.ipynb +0 -0
  95. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/fmu_cosimulation.ipynb +0 -0
  96. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/fmu_model_exchange_bouncing_ball.ipynb +0 -0
  97. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/fmu_model_exchange_vanderpol.ipynb +0 -0
  98. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/harmonic_oscillator.ipynb +0 -0
  99. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/kalman_filter.ipynb +0 -0
  100. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/linear_feedback.ipynb +0 -0
  101. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/lorenz_attractor.ipynb +0 -0
  102. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/nested_subsystems.ipynb +0 -0
  103. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/noisy_amplifier.ipynb +0 -0
  104. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/pendulum.ipynb +0 -0
  105. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/pid_controller.ipynb +0 -0
  106. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/poincare_maps.ipynb +0 -0
  107. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/rf_network_oneport.ipynb +0 -0
  108. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/sar_adc.ipynb +0 -0
  109. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/spectrum_analysis.ipynb +0 -0
  110. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/stick_slip.ipynb +0 -0
  111. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/switched_bouncing_ball.ipynb +0 -0
  112. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/thermostat.ipynb +0 -0
  113. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/transfer_function.ipynb +0 -0
  114. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples/vanderpol.ipynb +0 -0
  115. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/examples.rst +0 -0
  116. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/figures/pathsim_object_hierarchy_g.png +0 -0
  117. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/figures/pathsim_solver_hierarchy_g.png +0 -0
  118. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/figures/sin_cos_blockdiagram_g.png +0 -0
  119. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/figures/system_g.png +0 -0
  120. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/index.rst +0 -0
  121. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/logos/pathsim_icon.png +0 -0
  122. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/logos/pathsim_logo.png +0 -0
  123. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/logos/pathsim_simplistic_logo.png +0 -0
  124. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks._block.rst +0 -0
  125. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.adder.rst +0 -0
  126. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.amplifier.rst +0 -0
  127. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.comparator.rst +0 -0
  128. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.converters.rst +0 -0
  129. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.counter.rst +0 -0
  130. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.ctrl.rst +0 -0
  131. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.delay.rst +0 -0
  132. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.differentiator.rst +0 -0
  133. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.discrete.rst +0 -0
  134. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.dynsys.rst +0 -0
  135. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.filters.rst +0 -0
  136. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.fmu.rst +0 -0
  137. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.function.rst +0 -0
  138. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.integrator.rst +0 -0
  139. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.kalman.rst +0 -0
  140. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.lti.rst +0 -0
  141. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.math.rst +0 -0
  142. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.multiplier.rst +0 -0
  143. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.noise.rst +0 -0
  144. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.ode.rst +0 -0
  145. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.relay.rst +0 -0
  146. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.rf.rst +0 -0
  147. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.rng.rst +0 -0
  148. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.rst +0 -0
  149. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.scope.rst +0 -0
  150. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.sources.rst +0 -0
  151. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.spectrum.rst +0 -0
  152. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.switch.rst +0 -0
  153. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.table.rst +0 -0
  154. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.blocks.wrapper.rst +0 -0
  155. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.connection.rst +0 -0
  156. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.events._event.rst +0 -0
  157. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.events.condition.rst +0 -0
  158. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.events.rst +0 -0
  159. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.events.schedule.rst +0 -0
  160. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.events.zerocrossing.rst +0 -0
  161. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.optim.anderson.rst +0 -0
  162. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.optim.booster.rst +0 -0
  163. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.optim.numerical.rst +0 -0
  164. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.optim.operator.rst +0 -0
  165. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.optim.rst +0 -0
  166. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.simulation.rst +0 -0
  167. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers._rungekutta.rst +0 -0
  168. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers._solver.rst +0 -0
  169. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.bdf.rst +0 -0
  170. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.dirk2.rst +0 -0
  171. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.dirk3.rst +0 -0
  172. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.esdirk32.rst +0 -0
  173. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.esdirk4.rst +0 -0
  174. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.esdirk43.rst +0 -0
  175. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.esdirk54.rst +0 -0
  176. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.esdirk85.rst +0 -0
  177. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.euler.rst +0 -0
  178. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.gear.rst +0 -0
  179. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rk4.rst +0 -0
  180. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkbs32.rst +0 -0
  181. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkck54.rst +0 -0
  182. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkdp54.rst +0 -0
  183. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkdp87.rst +0 -0
  184. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkf21.rst +0 -0
  185. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkf45.rst +0 -0
  186. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkf78.rst +0 -0
  187. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rkv65.rst +0 -0
  188. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.rst +0 -0
  189. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.ssprk22.rst +0 -0
  190. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.ssprk33.rst +0 -0
  191. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.ssprk34.rst +0 -0
  192. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.solvers.steadystate.rst +0 -0
  193. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.subsystem.rst +0 -0
  194. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.adaptivebuffer.rst +0 -0
  195. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.analysis.rst +0 -0
  196. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.gilbert.rst +0 -0
  197. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.logger.rst +0 -0
  198. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.portreference.rst +0 -0
  199. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.progresstracker.rst +0 -0
  200. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.realtimeplotter.rst +0 -0
  201. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.register.rst +0 -0
  202. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/modules/pathsim.utils.rst +0 -0
  203. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/pathsim_docs.mplstyle +0 -0
  204. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/quickstart.ipynb +0 -0
  205. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/roadmap.rst +0 -0
  206. {pathsim-0.21.1 → pathsim-0.22.1}/docs/source/roadmap_generated.rst +0 -0
  207. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_abs_braking.py +0 -0
  208. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_adc.py +0 -0
  209. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_algebraicchain.py +0 -0
  210. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_algebraicloop.py +0 -0
  211. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_cascade.py +0 -0
  212. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_dcmotor.py +0 -0
  213. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_deltasigma.py +0 -0
  214. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_derivative.py +0 -0
  215. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_diode.py +0 -0
  216. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_dualslope.py +0 -0
  217. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_elastic_pendulum.py +0 -0
  218. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_feedback.py +0 -0
  219. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_filters.py +0 -0
  220. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_harmonic_oscillator.py +0 -0
  221. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_kalman_filter.py +0 -0
  222. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_nested_subsystems.py +0 -0
  223. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_noise.py +0 -0
  224. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_pendulum.py +0 -0
  225. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_phasenoise.py +0 -0
  226. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_pid.py +0 -0
  227. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_pid_antiwindup.py +0 -0
  228. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_pid_vs_discretePID.py +0 -0
  229. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_radar.py +0 -0
  230. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_reactor.py +0 -0
  231. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_sar.py +0 -0
  232. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_solar.py +0 -0
  233. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_solver_hotswap.py +0 -0
  234. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_spectrum.py +0 -0
  235. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_spectrum_rf_oneport.py +0 -0
  236. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_steadystate.py +0 -0
  237. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_stickslip.py +0 -0
  238. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_transferfunction.py +0 -0
  239. {pathsim-0.21.1 → pathsim-0.22.1}/examples/example_vanderpol_subsystem.py +0 -0
  240. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_billards_sphere.py +0 -0
  241. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_bouncing_pendulum.py +0 -0
  242. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_bouncingball.py +0 -0
  243. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_bouncingball_friction.py +0 -0
  244. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_bouncingball_switched.py +0 -0
  245. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_integrator_reset.py +0 -0
  246. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_pulse.py +0 -0
  247. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_stickslip_event.py +0 -0
  248. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_thermostat.py +0 -0
  249. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_event/example_volterralotka_event.py +0 -0
  250. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_bonhoeffer_vanderpol.py +0 -0
  251. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_brusselator.py +0 -0
  252. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_chemical.py +0 -0
  253. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_duffing.py +0 -0
  254. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_fairen_velarde.py +0 -0
  255. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_fitzhughnagumo.py +0 -0
  256. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_flame.py +0 -0
  257. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_glycolysis.py +0 -0
  258. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_lorenz.py +0 -0
  259. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_morse.py +0 -0
  260. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_robertson.py +0 -0
  261. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_roessler.py +0 -0
  262. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_thomas_cyclic.py +0 -0
  263. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_vanderpol.py +0 -0
  264. {pathsim-0.21.1 → pathsim-0.22.1}/examples/examples_odes/example_volterralotka.py +0 -0
  265. {pathsim-0.21.1 → pathsim-0.22.1}/git +0 -0
  266. {pathsim-0.21.1 → pathsim-0.22.1}/pyproject.toml +0 -0
  267. {pathsim-0.21.1 → pathsim-0.22.1}/setup.cfg +0 -0
  268. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/_constants.py +0 -0
  269. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/README.md +0 -0
  270. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/__init__.py +0 -0
  271. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/adder.py +0 -0
  272. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/amplifier.py +0 -0
  273. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/comparator.py +0 -0
  274. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/converters.py +0 -0
  275. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/counter.py +0 -0
  276. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/ctrl.py +0 -0
  277. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/delay.py +0 -0
  278. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/differentiator.py +0 -0
  279. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/discrete.py +0 -0
  280. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/divider.py +0 -0
  281. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/dynsys.py +0 -0
  282. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/filters.py +0 -0
  283. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/fmu.py +0 -0
  284. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/function.py +0 -0
  285. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/integrator.py +0 -0
  286. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/kalman.py +0 -0
  287. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/logic.py +0 -0
  288. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/lti.py +0 -0
  289. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/math.py +0 -0
  290. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/multiplier.py +0 -0
  291. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/noise.py +0 -0
  292. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/ode.py +0 -0
  293. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/relay.py +0 -0
  294. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/rf.py +0 -0
  295. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/rng.py +0 -0
  296. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/scope.py +0 -0
  297. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/sources.py +0 -0
  298. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/spectrum.py +0 -0
  299. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/switch.py +0 -0
  300. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/table.py +0 -0
  301. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/blocks/wrapper.py +0 -0
  302. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/events/__init__.py +0 -0
  303. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/events/_event.py +0 -0
  304. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/events/condition.py +0 -0
  305. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/events/schedule.py +0 -0
  306. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/events/zerocrossing.py +0 -0
  307. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/optim/__init__.py +0 -0
  308. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/optim/anderson.py +0 -0
  309. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/optim/booster.py +0 -0
  310. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/optim/numerical.py +0 -0
  311. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/optim/operator.py +0 -0
  312. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/README.md +0 -0
  313. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/__init__.py +0 -0
  314. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/_rungekutta.py +0 -0
  315. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/_solver.py +0 -0
  316. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/bdf.py +0 -0
  317. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/dirk2.py +0 -0
  318. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/dirk3.py +0 -0
  319. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/esdirk32.py +0 -0
  320. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/esdirk4.py +0 -0
  321. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/esdirk43.py +0 -0
  322. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/esdirk54.py +0 -0
  323. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/esdirk85.py +0 -0
  324. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/euler.py +0 -0
  325. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/gear.py +0 -0
  326. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rk4.py +0 -0
  327. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkbs32.py +0 -0
  328. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkck54.py +0 -0
  329. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkdp54.py +0 -0
  330. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkdp87.py +0 -0
  331. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkf21.py +0 -0
  332. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkf45.py +0 -0
  333. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkf78.py +0 -0
  334. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/rkv65.py +0 -0
  335. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/ssprk22.py +0 -0
  336. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/ssprk33.py +0 -0
  337. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/ssprk34.py +0 -0
  338. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/solvers/steadystate.py +0 -0
  339. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/subsystem.py +0 -0
  340. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/__init__.py +0 -0
  341. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/adaptivebuffer.py +0 -0
  342. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/analysis.py +0 -0
  343. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/deprecation.py +0 -0
  344. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/diagnostics.py +0 -0
  345. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/fmuwrapper.py +0 -0
  346. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/gilbert.py +0 -0
  347. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/graph.py +0 -0
  348. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/logger.py +0 -0
  349. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/mutable.py +0 -0
  350. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/portreference.py +0 -0
  351. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/progresstracker.py +0 -0
  352. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/realtimeplotter.py +0 -0
  353. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim/utils/register.py +0 -0
  354. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim.egg-info/dependency_links.txt +0 -0
  355. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim.egg-info/requires.txt +0 -0
  356. {pathsim-0.21.1 → pathsim-0.22.1}/src/pathsim.egg-info/top_level.txt +0 -0
  357. {pathsim-0.21.1 → pathsim-0.22.1}/tests/README.md +0 -0
  358. {pathsim-0.21.1 → pathsim-0.22.1}/tests/__init__.py +0 -0
  359. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/CoupledClutches_CS.fmu +0 -0
  360. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/__init__.py +0 -0
  361. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/conftest.py +0 -0
  362. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_algebraic_system.py +0 -0
  363. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_bouncingball_friction_event_system.py +0 -0
  364. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_bouncingball_system.py +0 -0
  365. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_brusselator_system.py +0 -0
  366. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_cosim_fmu_system.py +0 -0
  367. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_counter_comparator_system.py +0 -0
  368. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_dynamical_system_ivp.py +0 -0
  369. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_fitzhughnagumo_system.py +0 -0
  370. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_harmonic_oscillator_system.py +0 -0
  371. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_linear_feedback_system.py +0 -0
  372. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_logic_system.py +0 -0
  373. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_lorenz_system.py +0 -0
  374. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_me_analytical.py +0 -0
  375. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_model_exchange_fmu_system.py +0 -0
  376. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_pid_system.py +0 -0
  377. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_relay_thermostat_system.py +0 -0
  378. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_rescale_delay_system.py +0 -0
  379. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_robertson_system.py +0 -0
  380. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_roessler_system.py +0 -0
  381. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_signal_processing_system.py +0 -0
  382. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_steadystate_transient_system.py +0 -0
  383. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_switch_lti_system.py +0 -0
  384. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_vanderpol_system.py +0 -0
  385. {pathsim-0.21.1 → pathsim-0.22.1}/tests/evals/test_volterralotka_system.py +0 -0
  386. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/__init__.py +0 -0
  387. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/__init__.py +0 -0
  388. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/_embedding.py +0 -0
  389. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/rf/__init__.py +0 -0
  390. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/rf/ring_slot.s2p +0 -0
  391. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/rf/ring_slot_meas.s1p +0 -0
  392. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/rf/test_rf.py +0 -0
  393. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_adder.py +0 -0
  394. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_amplifier.py +0 -0
  395. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_comparator.py +0 -0
  396. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_converters.py +0 -0
  397. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_counter.py +0 -0
  398. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_ctrl.py +0 -0
  399. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_delay.py +0 -0
  400. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_differentiator.py +0 -0
  401. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_discrete.py +0 -0
  402. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_divider.py +0 -0
  403. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_dynsys.py +0 -0
  404. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_filters.py +0 -0
  405. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_fmu.py +0 -0
  406. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_function.py +0 -0
  407. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_integrator.py +0 -0
  408. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_kalman.py +0 -0
  409. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_logic.py +0 -0
  410. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_lti.py +0 -0
  411. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_math.py +0 -0
  412. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_multiplier.py +0 -0
  413. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_noise.py +0 -0
  414. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_ode.py +0 -0
  415. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_relay.py +0 -0
  416. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_rng.py +0 -0
  417. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_scope.py +0 -0
  418. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_sources.py +0 -0
  419. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_spectrum.py +0 -0
  420. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_switch.py +0 -0
  421. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_table.py +0 -0
  422. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/blocks/test_wrapper.py +0 -0
  423. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/events/__init__.py +0 -0
  424. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/events/test_condition.py +0 -0
  425. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/events/test_event.py +0 -0
  426. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/events/test_schedule.py +0 -0
  427. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/events/test_zerocrossing.py +0 -0
  428. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/optim/__init__.py +0 -0
  429. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/optim/test_anderson.py +0 -0
  430. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/optim/test_numerical.py +0 -0
  431. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/optim/test_operator.py +0 -0
  432. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/__init__.py +0 -0
  433. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/_referenceproblems.py +0 -0
  434. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_bdf.py +0 -0
  435. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_dirk2.py +0 -0
  436. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_dirk3.py +0 -0
  437. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_esdirk32.py +0 -0
  438. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_esdirk4.py +0 -0
  439. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_esdirk43.py +0 -0
  440. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_esdirk54.py +0 -0
  441. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_esdirk85.py +0 -0
  442. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_euler.py +0 -0
  443. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_gear.py +0 -0
  444. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rfk21.py +0 -0
  445. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rk4.py +0 -0
  446. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkbs32.py +0 -0
  447. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkck54.py +0 -0
  448. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkdp54.py +0 -0
  449. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkdp87.py +0 -0
  450. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkf45.py +0 -0
  451. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkf78.py +0 -0
  452. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_rkv65.py +0 -0
  453. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_solver.py +0 -0
  454. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_ssprk22.py +0 -0
  455. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_ssprk33.py +0 -0
  456. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_ssprk34.py +0 -0
  457. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/solvers/test_steadystate.py +0 -0
  458. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/test_checkpoint.py +0 -0
  459. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/test_diagnostics.py +0 -0
  460. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/test_subsystem.py +0 -0
  461. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/__init__.py +0 -0
  462. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_adaptivebuffer.py +0 -0
  463. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_analysis.py +0 -0
  464. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_fmuwrapper.py +0 -0
  465. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_gilbert.py +0 -0
  466. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_graph.py +0 -0
  467. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_logger.py +0 -0
  468. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_mutable.py +0 -0
  469. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_portreference.py +0 -0
  470. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_progresstracker.py +0 -0
  471. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_realtimeplotter.py +0 -0
  472. {pathsim-0.21.1 → pathsim-0.22.1}/tests/pathsim/utils/test_register.py +0 -0
@@ -12,12 +12,12 @@ jobs:
12
12
  deploy:
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v6
16
16
  with:
17
17
  fetch-depth: 0
18
18
 
19
19
  - name: Set up Python
20
- uses: actions/setup-python@v5
20
+ uses: actions/setup-python@v6
21
21
  with:
22
22
  python-version: '3.x'
23
23
 
@@ -4,9 +4,9 @@ jobs:
4
4
  test:
5
5
  runs-on: ubuntu-latest
6
6
  steps:
7
- - uses: actions/checkout@v4
7
+ - uses: actions/checkout@v6
8
8
  - name: Set up Python
9
- uses: actions/setup-python@v5
9
+ uses: actions/setup-python@v6
10
10
  with:
11
11
  python-version: '3.x'
12
12
  - name: Install dependencies
@@ -8,7 +8,7 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
 
10
10
  steps:
11
- - uses: actions/checkout@v4
11
+ - uses: actions/checkout@v6
12
12
  - name: urls-checker
13
13
  uses: urlstechie/urlchecker-action@master
14
14
  with:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pathsim
3
- Version: 0.21.1
3
+ Version: 0.22.1
4
4
  Summary: A differentiable block based hybrid system simulation framework.
5
5
  Author-email: Milan Rother <milan.rother@gmx.de>
6
6
  License: MIT
@@ -9,3 +9,4 @@ from .simulation import Simulation
9
9
  from .connection import Connection, Duplex
10
10
  from .subsystem import Subsystem, Interface
11
11
  from .utils.logger import LoggerManager
12
+ from .exceptions import StopSimulation
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.21.1'
22
- __version_tuple__ = version_tuple = (0, 21, 1)
21
+ __version__ = version = '0.22.1'
22
+ __version_tuple__ = version_tuple = (0, 22, 1)
23
23
 
24
- __commit_id__ = commit_id = 'g1f8538a26'
24
+ __commit_id__ = commit_id = 'g33dfc7866'
@@ -18,6 +18,32 @@ from ..utils.register import Register
18
18
  from ..utils.portreference import PortReference
19
19
 
20
20
 
21
+ # HELPERS ===============================================================================
22
+
23
+ def _labels_size(labels):
24
+ """Minimum register size required to hold all declared port labels.
25
+
26
+ Port labels map string aliases to integer port indices. The register has
27
+ to be large enough to address the highest declared index, otherwise blocks
28
+ with unconnected declared ports (e.g. a multi-input block placed without
29
+ connections) would default to the size 1 register and break positional
30
+ input access.
31
+
32
+ Parameters
33
+ ----------
34
+ labels : dict[str: int] | None
35
+ port label mapping (alias -> index)
36
+
37
+ Returns
38
+ -------
39
+ size : int | None
40
+ minimum register size, or None if no labels are declared
41
+ """
42
+ if not labels:
43
+ return None
44
+ return max(labels.values()) + 1
45
+
46
+
21
47
  # BASE BLOCK CLASS ======================================================================
22
48
 
23
49
  class Block:
@@ -84,11 +110,14 @@ class Block:
84
110
 
85
111
  def __init__(self):
86
112
 
87
- #registers to hold input and output values
113
+ #registers to hold input and output values, pre-sized to the declared
114
+ #port labels so blocks with unconnected ports are still addressable
88
115
  self.inputs = Register(
116
+ size=_labels_size(self.input_port_labels),
89
117
  mapping=self.input_port_labels and self.input_port_labels.copy()
90
118
  )
91
119
  self.outputs = Register(
120
+ size=_labels_size(self.output_port_labels),
92
121
  mapping=self.output_port_labels and self.output_port_labels.copy()
93
122
  )
94
123
 
@@ -249,6 +249,30 @@ class Connection:
249
249
  self.source.to(trg)
250
250
 
251
251
 
252
+ def resolve_ports(self):
253
+ """Eagerly resolve source and target port indices, growing the
254
+ underlying ``Register`` instances to their final size.
255
+
256
+ Normally registers grow lazily on the first ``connection.update()``
257
+ via ``PortReference._get_input_indices``. In the DAG case that is
258
+ fine: the source-side connection fires before the target block's
259
+ ``update``, so by the time the block reads its inputs, the
260
+ register has the right size. Inside an algebraic loop the order
261
+ is reversed (``block.update()`` first, then ``connection.update()``
262
+ in the same iteration), so the first iteration sees a register
263
+ still at the ``Block.__init__`` default size and any block that
264
+ accesses inputs by position (e.g. ``Function`` splatting into a
265
+ multi-arg callable) raises ``TypeError``.
266
+
267
+ Calling ``resolve_ports`` once during graph assembly closes that
268
+ gap. Idempotent. New register slots are zero-initialised through
269
+ ``np.zeros`` in ``Register.resize``.
270
+ """
271
+ self.source._get_output_indices()
272
+ for trg in self.targets:
273
+ trg._get_input_indices()
274
+
275
+
252
276
  @deprecated(version="1.0.0")
253
277
  class Duplex(Connection):
254
278
  """Extension of the 'Connection' class, that defines bidirectional
@@ -0,0 +1,44 @@
1
+ #########################################################################################
2
+ ##
3
+ ## PATHSIM EXCEPTIONS
4
+ ## (exceptions.py)
5
+ ##
6
+ ## This module defines custom exceptions for the PathSim simulation framework.
7
+ ##
8
+ #########################################################################################
9
+
10
+
11
+ class StopSimulation(Exception):
12
+ """Exception that can be raised by blocks or models to signal that the
13
+ simulation should stop immediately.
14
+
15
+ This provides a clean mechanism for user-defined stopping conditions,
16
+ such as reaching a target state, detecting a fault, or satisfying
17
+ a convergence criterion.
18
+
19
+ When raised inside a block's update, sample, or any other method
20
+ called during the simulation loop, the 'Simulation' class will catch
21
+ it gracefully and terminate the run as if 'stop()' had been called.
22
+
23
+ Parameters
24
+ ----------
25
+ message : str
26
+ optional message describing the stopping condition
27
+
28
+ Example
29
+ -------
30
+
31
+ Raise from inside a block to stop the simulation:
32
+
33
+ .. code-block:: python
34
+
35
+ from pathsim.exceptions import StopSimulation
36
+ from pathsim.blocks import Function
37
+
38
+ def check(x):
39
+ if x > 10.0:
40
+ raise StopSimulation(f"value exceeded threshold: {x:.4f}")
41
+ return x
42
+
43
+ blk = Function(check)
44
+ """
@@ -47,6 +47,7 @@ from .blocks._block import Block
47
47
  from .events._event import Event
48
48
 
49
49
  from .connection import Connection
50
+ from .exceptions import StopSimulation
50
51
 
51
52
 
52
53
  # TRANSIENT SIMULATION CLASS ============================================================
@@ -690,6 +691,12 @@ class Simulation:
690
691
  for block in self.blocks:
691
692
  block.inputs.reset()
692
693
 
694
+ #resolve all port indices so input/output registers are sized before
695
+ #graph assembly evaluates block passthrough via len(block) and before
696
+ #any block.update() runs (see Connection.resolve_ports)
697
+ for con in self.connections:
698
+ con.resolve_ports()
699
+
693
700
  #time the graph construction
694
701
  with Timer(verbose=False) as T:
695
702
  self.graph = Graph(self.blocks, self.connections)
@@ -1472,14 +1479,17 @@ class Simulation:
1472
1479
 
1473
1480
  #implicit solver didn't converge
1474
1481
  if not success:
1475
- details = self._solve_tracker.details(lambda b: b.__class__.__name__)
1476
1482
  if is_adaptive:
1477
- self.logger.warning(
1478
- "implicit solver not converged, reverting step at t={:.6f}\n{}".format(
1479
- time_stage, "\n".join(details)))
1483
+ #adaptive stepping: a non-converged solve is
1484
+ #the expected signal to halve the step and
1485
+ #retry. revert silently — same handling as the
1486
+ #LTE failure below. residuals stay available
1487
+ #via self._solve_tracker for diagnostics.
1480
1488
  self._revert(self.time)
1481
1489
  return False, 0.0, 0.5, total_evals + 1, total_solver_its
1482
1490
  else:
1491
+ #fixed-step: user has no recovery path, log it
1492
+ details = self._solve_tracker.details(lambda b: b.__class__.__name__)
1483
1493
  self.logger.warning(
1484
1494
  "implicit solver not converged at t={:.6f} (iters: {})\n{}".format(
1485
1495
  time_stage, solver_its, "\n".join(details)))
@@ -1623,16 +1633,22 @@ class Simulation:
1623
1633
  _dt = self.dt
1624
1634
 
1625
1635
  #initial system function evaluation
1626
- self._update(self.time)
1636
+ try:
1637
+ self._update(self.time)
1627
1638
 
1628
- #catch and resolve initial events
1629
- for event, *_ in self._detected_events(self.time):
1639
+ #catch and resolve initial events
1640
+ for event, *_ in self._detected_events(self.time):
1630
1641
 
1631
- #resolve events directly
1632
- event.resolve(self.time)
1642
+ #resolve events directly
1643
+ event.resolve(self.time)
1633
1644
 
1634
- #evaluate system function again -> propagate event
1635
- self._update(self.time)
1645
+ #evaluate system function again -> propagate event
1646
+ self._update(self.time)
1647
+
1648
+ except StopSimulation as e:
1649
+ self.logger.info(f"STOP (StopSimulation: '{e}')")
1650
+ self._active = False
1651
+ return
1636
1652
 
1637
1653
  #sampling states and inputs at 'self.time == starting_time'
1638
1654
  self._sample(self.time, _dt)
@@ -1641,10 +1657,15 @@ class Simulation:
1641
1657
  while self.time < end_time and self._active:
1642
1658
 
1643
1659
  #advance the simulation by one (effective) timestep '_dt'
1644
- success, error_norm, scale, *_ = self.timestep(
1645
- dt=_dt,
1646
- adaptive=_adaptive
1647
- )
1660
+ try:
1661
+ success, error_norm, scale, *_ = self.timestep(
1662
+ dt=_dt,
1663
+ adaptive=_adaptive
1664
+ )
1665
+ except StopSimulation as e:
1666
+ self.logger.info(f"STOP (StopSimulation: '{e}')")
1667
+ self._active = False
1668
+ break
1648
1669
 
1649
1670
  #perform adaptive rescale
1650
1671
  if _adaptive:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pathsim
3
- Version: 0.21.1
3
+ Version: 0.22.1
4
4
  Summary: A differentiable block based hybrid system simulation framework.
5
5
  Author-email: Milan Rother <milan.rother@gmx.de>
6
6
  License: MIT
@@ -256,6 +256,7 @@ src/pathsim/__init__.py
256
256
  src/pathsim/_constants.py
257
257
  src/pathsim/_version.py
258
258
  src/pathsim/connection.py
259
+ src/pathsim/exceptions.py
259
260
  src/pathsim/simulation.py
260
261
  src/pathsim/subsystem.py
261
262
  src/pathsim.egg-info/PKG-INFO
@@ -254,6 +254,33 @@ class TestBlock(unittest.TestCase):
254
254
  self.assertEqual(cache_info.misses, 1)
255
255
 
256
256
 
257
+ def test_register_sizing_from_port_labels(self):
258
+ """Registers are pre-sized to the declared port labels so blocks
259
+ with unconnected multi-port interfaces stay positionally addressable.
260
+ """
261
+
262
+ class _LabeledBlock(Block):
263
+ input_port_labels = {"a": 0, "b": 1}
264
+ output_port_labels = {"x": 0, "y": 1, "z": 2}
265
+
266
+ B = _LabeledBlock()
267
+
268
+ #registers sized to highest declared index + 1
269
+ self.assertEqual(len(B.inputs), 2)
270
+ self.assertEqual(len(B.outputs), 3)
271
+
272
+ #shape reflects declared ports even without connections
273
+ self.assertEqual(B.shape, (2, 3))
274
+
275
+ #all declared ports addressable and zero-initialized
276
+ self.assertEqual(B.inputs["b"], 0.0)
277
+ self.assertEqual(B.outputs["z"], 0.0)
278
+
279
+ #blocks without port labels keep the default size 1 registers
280
+ self.assertEqual(len(Block().inputs), 1)
281
+ self.assertEqual(len(Block().outputs), 1)
282
+
283
+
257
284
  # RUN TESTS LOCALLY ====================================================================
258
285
 
259
286
  if __name__ == '__main__':
@@ -141,7 +141,7 @@ class TestConnection(unittest.TestCase):
141
141
 
142
142
 
143
143
  def test_on_off_bool(self):
144
-
144
+
145
145
  B1, B2 = Block(), Block()
146
146
 
147
147
  #default
@@ -159,6 +159,62 @@ class TestConnection(unittest.TestCase):
159
159
  self.assertTrue(C)
160
160
 
161
161
 
162
+ def test_resolve_ports_grows_input_register(self):
163
+ """resolve_ports must size the target input register so blocks
164
+ accessing inputs by position before any connection.update() runs
165
+ (e.g. inside an algebraic loop) see the correct number of slots.
166
+ """
167
+ B1, B2 = Block(), Block()
168
+
169
+ #fresh block has size-1 input register from Block.__init__
170
+ self.assertEqual(len(B2.inputs), 1)
171
+
172
+ C = Connection(B1[2], B2[3])
173
+
174
+ #ports validated but lazy resize not yet triggered
175
+ self.assertEqual(len(B2.inputs), 1)
176
+ self.assertEqual(len(B1.outputs), 1)
177
+
178
+ C.resolve_ports()
179
+
180
+ #both registers must accommodate the highest port index
181
+ self.assertEqual(len(B2.inputs), 4)
182
+ self.assertEqual(len(B1.outputs), 3)
183
+
184
+ #new slots are zero-initialised
185
+ self.assertEqual(B2.inputs[3], 0.0)
186
+
187
+
188
+ def test_resolve_ports_is_idempotent(self):
189
+ """Repeated calls must not change register size or contents."""
190
+ B1, B2 = Block(), Block()
191
+ C = Connection(B1[5], B2[7])
192
+
193
+ C.resolve_ports()
194
+ size_in = len(B2.inputs)
195
+ size_out = len(B1.outputs)
196
+
197
+ #seed a value so we can detect data loss on a second resolve
198
+ B2.inputs[7] = 42.0
199
+
200
+ C.resolve_ports()
201
+ self.assertEqual(len(B2.inputs), size_in)
202
+ self.assertEqual(len(B1.outputs), size_out)
203
+ self.assertEqual(B2.inputs[7], 42.0)
204
+
205
+
206
+ def test_resolve_ports_multi_target(self):
207
+ """All targets must be resolved, not just the first."""
208
+ B1, B2, B3 = Block(), Block(), Block()
209
+ C = Connection(B1[1], B2[4], B3[6])
210
+
211
+ C.resolve_ports()
212
+
213
+ self.assertEqual(len(B1.outputs), 2)
214
+ self.assertEqual(len(B2.inputs), 5)
215
+ self.assertEqual(len(B3.inputs), 7)
216
+
217
+
162
218
 
163
219
  class TestDuplex(unittest.TestCase):
164
220
  """
@@ -21,9 +21,11 @@ from pathsim.connection import Connection
21
21
  #modules from pathsim for test case
22
22
  from pathsim.blocks import (
23
23
  Integrator,
24
- Amplifier,
25
- Scope,
26
- Adder
24
+ Amplifier,
25
+ Scope,
26
+ Adder,
27
+ Function,
28
+ Constant,
27
29
  )
28
30
 
29
31
  from pathsim._constants import (
@@ -37,6 +39,7 @@ from pathsim._constants import (
37
39
  from pathsim.blocks import Source, Relay
38
40
  from pathsim.events.schedule import Schedule
39
41
  from pathsim.events._event import Event
42
+ from pathsim.exceptions import StopSimulation
40
43
 
41
44
 
42
45
  # TESTS ================================================================================
@@ -754,6 +757,82 @@ class TestSimulationAdvanced(unittest.TestCase):
754
757
  self.assertLess(self.Sim.time, 5.0)
755
758
 
756
759
 
760
+ def test_stop_simulation_exception_stops_run(self):
761
+ """StopSimulation raised by a block stops run() without propagating"""
762
+
763
+ threshold = 0.5 # Int state starts at 1 and decays — stop when below this
764
+
765
+ def guard(x):
766
+ if x < threshold:
767
+ raise StopSimulation(f"value dropped below {threshold}")
768
+ return x
769
+
770
+ guard_block = Function(guard)
771
+ self.Sim.add_block(guard_block)
772
+ self.Sim.add_connection(Connection(self.Int, guard_block))
773
+
774
+ # should not raise, and should stop before duration=5
775
+ self.Sim.run(duration=5.0, reset=True)
776
+
777
+ self.assertFalse(self.Sim._active)
778
+ self.assertLess(self.Sim.time, 5.0)
779
+
780
+
781
+ def test_stop_simulation_at_first_step(self):
782
+ """StopSimulation raised immediately leaves sim.time at start"""
783
+
784
+ call_count = [0]
785
+
786
+ def always_stop(x):
787
+ call_count[0] += 1
788
+ raise StopSimulation("stop immediately")
789
+
790
+ guard_block = Function(always_stop)
791
+ self.Sim.add_block(guard_block)
792
+ self.Sim.add_connection(Connection(self.Int, guard_block))
793
+
794
+ start_time = self.Sim.time
795
+ self.Sim.run(duration=5.0, reset=False)
796
+
797
+ self.assertFalse(self.Sim._active)
798
+ self.assertEqual(self.Sim.time, start_time)
799
+
800
+
801
+ def test_stop_simulation_exception_stops_run_streaming(self):
802
+ """StopSimulation raised by a block terminates run_streaming cleanly"""
803
+
804
+ threshold = 0.5
805
+
806
+ def guard(x):
807
+ if x < threshold:
808
+ raise StopSimulation("streaming stop")
809
+ return x
810
+
811
+ guard_block = Function(guard)
812
+ self.Sim.add_block(guard_block)
813
+ self.Sim.add_connection(Connection(self.Int, guard_block))
814
+
815
+ results = list(self.Sim.run_streaming(
816
+ duration=5.0,
817
+ reset=True,
818
+ tickrate=100,
819
+ func_callback=lambda: self.Sim.time
820
+ ))
821
+
822
+ self.assertFalse(self.Sim._active)
823
+ self.assertLess(self.Sim.time, 5.0)
824
+ self.assertGreater(len(results), 0)
825
+
826
+
827
+ def test_stop_simulation_no_exception_normal_run(self):
828
+ """Regression: normal run without StopSimulation completes fully"""
829
+
830
+ self.Sim.run(duration=2.0, reset=True)
831
+
832
+ self.assertAlmostEqual(self.Sim.time, 2.0, 5)
833
+ self.assertTrue(self.Sim._active)
834
+
835
+
757
836
  def test_deprecated_timestep_methods(self):
758
837
  """Test deprecated timestep methods still work"""
759
838
 
@@ -1045,6 +1124,65 @@ class TestSimulationRuntimeMutation(unittest.TestCase):
1045
1124
  self.assertGreater(len(time), 0)
1046
1125
 
1047
1126
 
1127
+ class TestSimulationAlgebraicLoop(unittest.TestCase):
1128
+ """Regression tests for algebraic-loop port resolution.
1129
+
1130
+ In an algebraic loop the iteration order is block.update() ->
1131
+ connection.update(). Without eager port resolution during graph
1132
+ assembly the first iteration would see input registers still at
1133
+ their Block.__init__ default size, and any block accessing inputs
1134
+ by position (Function splatting into a multi-arg lambda) would
1135
+ raise TypeError.
1136
+ """
1137
+
1138
+ def test_function_in_algebraic_loop_runs(self):
1139
+ """Function with multi-arg lambda inside algebraic loop must run."""
1140
+
1141
+ c = Constant(value=1.0)
1142
+ A = Function(lambda u, fb: u + 0.1 * fb)
1143
+ B = Function(lambda x: 0.5 * x)
1144
+
1145
+ blocks = [c, A, B]
1146
+ connections = [
1147
+ Connection(c, A[0]),
1148
+ Connection(A, B),
1149
+ Connection(B, A[1]), # closes the loop
1150
+ ]
1151
+
1152
+ Sim = Simulation(blocks, connections, dt=0.01, log=False)
1153
+
1154
+ #without eager resolution this would raise TypeError on the first
1155
+ #step ("missing 1 required positional argument: 'fb'")
1156
+ Sim.run(duration=0.05)
1157
+
1158
+ #fixed point: A = 1 + 0.1 * 0.5 * A -> A = 1 / 0.95
1159
+ self.assertAlmostEqual(float(A.outputs[0]), 1.0 / 0.95, 6)
1160
+
1161
+
1162
+ def test_assemble_graph_resolves_all_connections(self):
1163
+ """After Simulation init every connection's registers are sized."""
1164
+
1165
+ c = Constant(value=1.0)
1166
+ A = Function(lambda u, fb: u + fb)
1167
+ B = Function(lambda x: x)
1168
+
1169
+ blocks = [c, A, B]
1170
+ connections = [
1171
+ Connection(c, A[0]),
1172
+ Connection(A, B),
1173
+ Connection(B, A[1]),
1174
+ ]
1175
+
1176
+ Simulation(blocks, connections, dt=0.01, log=False)
1177
+
1178
+ #all registers must reach their final size during _assemble_graph
1179
+ self.assertGreaterEqual(len(A.inputs), 2)
1180
+ self.assertGreaterEqual(len(B.inputs), 1)
1181
+ self.assertGreaterEqual(len(c.outputs), 1)
1182
+ self.assertGreaterEqual(len(A.outputs), 1)
1183
+ self.assertGreaterEqual(len(B.outputs), 1)
1184
+
1185
+
1048
1186
  # RUN TESTS LOCALLY ====================================================================
1049
1187
 
1050
1188
  if __name__ == '__main__':
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes