pathsim 0.27.0__tar.gz → 0.28.0__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 (396) hide show
  1. {pathsim-0.27.0 → pathsim-0.28.0}/PKG-INFO +3 -3
  2. {pathsim-0.27.0 → pathsim-0.28.0}/pyproject.toml +2 -2
  3. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/_version.py +3 -3
  4. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/dae.py +511 -16
  5. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/delay.py +13 -4
  6. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/__init__.py +1 -0
  7. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/anderson.py +89 -3
  8. pathsim-0.28.0/src/pathsim/optim/jacobian.py +144 -0
  9. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/operator.py +29 -3
  10. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/simulation.py +4 -0
  11. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/PKG-INFO +3 -3
  12. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/SOURCES.txt +4 -0
  13. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/requires.txt +2 -2
  14. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/scm_file_list.json +4 -0
  15. pathsim-0.28.0/src/pathsim.egg-info/scm_version.json +8 -0
  16. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_dae.py +78 -1
  17. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_delay.py +56 -1
  18. pathsim-0.28.0/tests/pathsim/blocks/test_delay_channels.py +64 -0
  19. pathsim-0.28.0/tests/pathsim/blocks/test_sparsedae.py +219 -0
  20. pathsim-0.28.0/tests/pathsim/optim/test_sparse_newton.py +264 -0
  21. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_simulation.py +85 -3
  22. pathsim-0.27.0/src/pathsim.egg-info/scm_version.json +0 -8
  23. {pathsim-0.27.0 → pathsim-0.28.0}/.codecov.yml +0 -0
  24. {pathsim-0.27.0 → pathsim-0.28.0}/.github/FUNDING.yml +0 -0
  25. {pathsim-0.27.0 → pathsim-0.28.0}/.github/pull_request_template.md +0 -0
  26. {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/pypi_deployment.yml +0 -0
  27. {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/tests_codecov.yml +0 -0
  28. {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/urlchecker.yml +0 -0
  29. {pathsim-0.27.0 → pathsim-0.28.0}/.gitignore +0 -0
  30. {pathsim-0.27.0 → pathsim-0.28.0}/CITATION.cff +0 -0
  31. {pathsim-0.27.0 → pathsim-0.28.0}/CONTRIBUTING.md +0 -0
  32. {pathsim-0.27.0 → pathsim-0.28.0}/LICENSE.txt +0 -0
  33. {pathsim-0.27.0 → pathsim-0.28.0}/README.md +0 -0
  34. {pathsim-0.27.0 → pathsim-0.28.0}/conftest.py +0 -0
  35. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/abs_braking.ipynb +0 -0
  36. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/algebraic_loop.ipynb +0 -0
  37. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/billards.ipynb +0 -0
  38. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/bouncing_ball.ipynb +0 -0
  39. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/bouncing_pendulum.ipynb +0 -0
  40. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/cascade_controller.ipynb +0 -0
  41. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/checkpoints.ipynb +0 -0
  42. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/chemical_reactor.ipynb +0 -0
  43. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/coupled_oscillators.ipynb +0 -0
  44. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/BouncingBall_ME.fmu +0 -0
  45. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/CoupledClutches_CS_linux64.fmu +0 -0
  46. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/CoupledClutches_CS_win64.fmu +0 -0
  47. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/Dahlquist.fmu +0 -0
  48. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/VanDerPol_ME.fmu +0 -0
  49. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/dcmotor_control.ipynb +0 -0
  50. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/delta_sigma_adc.ipynb +0 -0
  51. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/diode_circuit.ipynb +0 -0
  52. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/elastic_pendulum.ipynb +0 -0
  53. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/algebraicloop_blockdiagram_g.png +0 -0
  54. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/billard_circle_g.png +0 -0
  55. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_blockdiagram_g.png +0 -0
  56. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_both_g.png +0 -0
  57. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_g.png +0 -0
  58. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_events_g.png +0 -0
  59. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_g.png +0 -0
  60. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_timesteps_g.png +0 -0
  61. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_pendulum_blockdiagram_g.png +0 -0
  62. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/cascade_blockdiagram_g.png +0 -0
  63. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/coupled_oscillators_blockdiagram_g.png +0 -0
  64. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/coupled_oscillators_g.png +0 -0
  65. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/delta_sigma_blockdiagram_g.png +0 -0
  66. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/diode_blockdiagram_g.png +0 -0
  67. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/elastic_pendulum_g.png +0 -0
  68. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/fmcw_blockdiagram_g.png +0 -0
  69. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/fmcw_g.png +0 -0
  70. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_g.png +0 -0
  71. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_result_g.png +0 -0
  72. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/kalman_filter_blockdiagram_g.png +0 -0
  73. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_blockdiagram_g.png +0 -0
  74. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_result_g.png +0 -0
  75. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_result_sensitivity_g.png +0 -0
  76. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/miller_frequency_divider_blockdiagram_g.png +0 -0
  77. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/nonlinear_noisy_amplifier_blockdiagram_g.png +0 -0
  78. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/ode_blockdiagram_g.png +0 -0
  79. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/pendulum_blockdiagram_g.png +0 -0
  80. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/pid_blockdiagram_g.png +0 -0
  81. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/sar_adc_blockdiagram_g.png +0 -0
  82. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_g.png +0 -0
  83. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_slip_g.png +0 -0
  84. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_stick_g.png +0 -0
  85. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_g.png +0 -0
  86. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/thermostat_blockdiagram_g.png +0 -0
  87. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_blockdiagram_g.png +0 -0
  88. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_result_g.png +0 -0
  89. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_blockdiagram_g.png +0 -0
  90. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl1_g.png +0 -0
  91. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl2_g.png +0 -0
  92. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl3_g.png +0 -0
  93. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/volterralotka_blockdiagram_g.png +0 -0
  94. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/ode_blockdiagram_2.png +0 -0
  95. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/stick_slip_blockdiagram_slip.png +0 -0
  96. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/stick_slip_blockdiagram_stick.png +0 -0
  97. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmcw_radar.ipynb +0 -0
  98. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_cosimulation.ipynb +0 -0
  99. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_model_exchange_bouncing_ball.ipynb +0 -0
  100. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_model_exchange_vanderpol.ipynb +0 -0
  101. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/harmonic_oscillator.ipynb +0 -0
  102. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/kalman_filter.ipynb +0 -0
  103. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/linear_feedback.ipynb +0 -0
  104. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/lorenz_attractor.ipynb +0 -0
  105. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/nested_subsystems.ipynb +0 -0
  106. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/noisy_amplifier.ipynb +0 -0
  107. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/pendulum.ipynb +0 -0
  108. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/pid_controller.ipynb +0 -0
  109. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/poincare_maps.ipynb +0 -0
  110. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/rf_network_oneport.ipynb +0 -0
  111. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/sar_adc.ipynb +0 -0
  112. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/spectrum_analysis.ipynb +0 -0
  113. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/stick_slip.ipynb +0 -0
  114. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/switched_bouncing_ball.ipynb +0 -0
  115. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/thermostat.ipynb +0 -0
  116. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/transfer_function.ipynb +0 -0
  117. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/vanderpol.ipynb +0 -0
  118. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_icon.png +0 -0
  119. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_logo.png +0 -0
  120. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_simplistic_logo.png +0 -0
  121. {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/pathsim_docs.mplstyle +0 -0
  122. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_abs_braking.py +0 -0
  123. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_adc.py +0 -0
  124. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_algebraicchain.py +0 -0
  125. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_algebraicloop.py +0 -0
  126. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_cascade.py +0 -0
  127. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_dcmotor.py +0 -0
  128. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_deltasigma.py +0 -0
  129. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_derivative.py +0 -0
  130. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_diode.py +0 -0
  131. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_dualslope.py +0 -0
  132. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_elastic_pendulum.py +0 -0
  133. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_feedback.py +0 -0
  134. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_filters.py +0 -0
  135. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_harmonic_oscillator.py +0 -0
  136. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_kalman_filter.py +0 -0
  137. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_nested_subsystems.py +0 -0
  138. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_noise.py +0 -0
  139. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pendulum.py +0 -0
  140. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_phasenoise.py +0 -0
  141. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid.py +0 -0
  142. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid_antiwindup.py +0 -0
  143. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid_vs_discretePID.py +0 -0
  144. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_radar.py +0 -0
  145. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_reactor.py +0 -0
  146. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_sar.py +0 -0
  147. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_solar.py +0 -0
  148. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_solver_hotswap.py +0 -0
  149. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_spectrum.py +0 -0
  150. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_spectrum_rf_oneport.py +0 -0
  151. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_steadystate.py +0 -0
  152. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_stickslip.py +0 -0
  153. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_transferfunction.py +0 -0
  154. {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_vanderpol_subsystem.py +0 -0
  155. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_billards_sphere.py +0 -0
  156. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncing_pendulum.py +0 -0
  157. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball.py +0 -0
  158. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball_friction.py +0 -0
  159. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball_switched.py +0 -0
  160. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_integrator_reset.py +0 -0
  161. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_pulse.py +0 -0
  162. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_stickslip_event.py +0 -0
  163. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_thermostat.py +0 -0
  164. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_volterralotka_event.py +0 -0
  165. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_bonhoeffer_vanderpol.py +0 -0
  166. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_brusselator.py +0 -0
  167. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_chemical.py +0 -0
  168. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_duffing.py +0 -0
  169. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_fairen_velarde.py +0 -0
  170. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_fitzhughnagumo.py +0 -0
  171. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_flame.py +0 -0
  172. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_glycolysis.py +0 -0
  173. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_lorenz.py +0 -0
  174. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_morse.py +0 -0
  175. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_robertson.py +0 -0
  176. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_roessler.py +0 -0
  177. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_thomas_cyclic.py +0 -0
  178. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_vanderpol.py +0 -0
  179. {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_volterralotka.py +0 -0
  180. {pathsim-0.27.0 → pathsim-0.28.0}/git +0 -0
  181. {pathsim-0.27.0 → pathsim-0.28.0}/setup.cfg +0 -0
  182. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/__init__.py +0 -0
  183. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/_constants.py +0 -0
  184. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/README.md +0 -0
  185. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/__init__.py +0 -0
  186. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/_block.py +0 -0
  187. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/adder.py +0 -0
  188. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/amplifier.py +0 -0
  189. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/bvp.py +0 -0
  190. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/comparator.py +0 -0
  191. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/constraint.py +0 -0
  192. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/converters.py +0 -0
  193. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/counter.py +0 -0
  194. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/ctrl.py +0 -0
  195. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/differentiator.py +0 -0
  196. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/discrete.py +0 -0
  197. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/divider.py +0 -0
  198. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/dynsys.py +0 -0
  199. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/filters.py +0 -0
  200. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/fmu.py +0 -0
  201. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/function.py +0 -0
  202. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/integrator.py +0 -0
  203. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/kalman.py +0 -0
  204. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/logic.py +0 -0
  205. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/lti.py +0 -0
  206. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/math.py +0 -0
  207. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/multiplier.py +0 -0
  208. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/noise.py +0 -0
  209. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/ode.py +0 -0
  210. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/relay.py +0 -0
  211. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/rf.py +0 -0
  212. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/rng.py +0 -0
  213. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/scope.py +0 -0
  214. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/sources.py +0 -0
  215. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/spectrum.py +0 -0
  216. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/switch.py +0 -0
  217. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/table.py +0 -0
  218. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/wrapper.py +0 -0
  219. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/connection.py +0 -0
  220. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/__init__.py +0 -0
  221. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/_event.py +0 -0
  222. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/condition.py +0 -0
  223. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/schedule.py +0 -0
  224. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/zerocrossing.py +0 -0
  225. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/exceptions.py +0 -0
  226. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/booster.py +0 -0
  227. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/linearization.py +0 -0
  228. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/newton.py +0 -0
  229. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/numerical.py +0 -0
  230. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/README.md +0 -0
  231. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/__init__.py +0 -0
  232. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/_rungekutta.py +0 -0
  233. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/_solver.py +0 -0
  234. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/bdf.py +0 -0
  235. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/dirk2.py +0 -0
  236. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/dirk3.py +0 -0
  237. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk32.py +0 -0
  238. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk4.py +0 -0
  239. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk43.py +0 -0
  240. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk54.py +0 -0
  241. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk85.py +0 -0
  242. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/euler.py +0 -0
  243. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/gear.py +0 -0
  244. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rk4.py +0 -0
  245. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkbs32.py +0 -0
  246. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkck54.py +0 -0
  247. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkdp54.py +0 -0
  248. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkdp87.py +0 -0
  249. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf21.py +0 -0
  250. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf45.py +0 -0
  251. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf78.py +0 -0
  252. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkv65.py +0 -0
  253. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk22.py +0 -0
  254. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk33.py +0 -0
  255. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk34.py +0 -0
  256. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/steadystate.py +0 -0
  257. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/subsystem.py +0 -0
  258. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/__init__.py +0 -0
  259. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/adaptivebuffer.py +0 -0
  260. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/analysis.py +0 -0
  261. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/deprecation.py +0 -0
  262. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/diagnostics.py +0 -0
  263. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/fmuwrapper.py +0 -0
  264. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/gilbert.py +0 -0
  265. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/graph.py +0 -0
  266. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/logger.py +0 -0
  267. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/mutable.py +0 -0
  268. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/portreference.py +0 -0
  269. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/progresstracker.py +0 -0
  270. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/realtimeplotter.py +0 -0
  271. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/register.py +0 -0
  272. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/dependency_links.txt +0 -0
  273. {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/top_level.txt +0 -0
  274. {pathsim-0.27.0 → pathsim-0.28.0}/tests/README.md +0 -0
  275. {pathsim-0.27.0 → pathsim-0.28.0}/tests/__init__.py +0 -0
  276. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/CoupledClutches_CS.fmu +0 -0
  277. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/__init__.py +0 -0
  278. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/conftest.py +0 -0
  279. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_algebraic_system.py +0 -0
  280. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_bouncingball_friction_event_system.py +0 -0
  281. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_bouncingball_system.py +0 -0
  282. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_brusselator_system.py +0 -0
  283. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_cosim_fmu_system.py +0 -0
  284. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_counter_comparator_system.py +0 -0
  285. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_dynamical_system_ivp.py +0 -0
  286. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_fitzhughnagumo_system.py +0 -0
  287. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_harmonic_oscillator_system.py +0 -0
  288. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_linear_feedback_system.py +0 -0
  289. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_logic_system.py +0 -0
  290. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_lorenz_system.py +0 -0
  291. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_me_analytical.py +0 -0
  292. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_model_exchange_fmu_system.py +0 -0
  293. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_pid_system.py +0 -0
  294. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_relay_thermostat_system.py +0 -0
  295. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_rescale_delay_system.py +0 -0
  296. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_robertson_system.py +0 -0
  297. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_roessler_system.py +0 -0
  298. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_signal_processing_system.py +0 -0
  299. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_steadystate_transient_system.py +0 -0
  300. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_switch_lti_system.py +0 -0
  301. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_vanderpol_system.py +0 -0
  302. {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_volterralotka_system.py +0 -0
  303. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/__init__.py +0 -0
  304. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/__init__.py +0 -0
  305. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/_embedding.py +0 -0
  306. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/__init__.py +0 -0
  307. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/ring_slot.s2p +0 -0
  308. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/ring_slot_meas.s1p +0 -0
  309. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/test_rf.py +0 -0
  310. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_adder.py +0 -0
  311. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_amplifier.py +0 -0
  312. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_block.py +0 -0
  313. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_bvp.py +0 -0
  314. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_comparator.py +0 -0
  315. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_constraint.py +0 -0
  316. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_converters.py +0 -0
  317. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_counter.py +0 -0
  318. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_ctrl.py +0 -0
  319. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_differentiator.py +0 -0
  320. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_discrete.py +0 -0
  321. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_divider.py +0 -0
  322. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_dynsys.py +0 -0
  323. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_filters.py +0 -0
  324. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_fmu.py +0 -0
  325. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_function.py +0 -0
  326. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_integrator.py +0 -0
  327. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_kalman.py +0 -0
  328. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_logic.py +0 -0
  329. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_lti.py +0 -0
  330. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_math.py +0 -0
  331. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_multiplier.py +0 -0
  332. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_noise.py +0 -0
  333. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_ode.py +0 -0
  334. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_relay.py +0 -0
  335. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_rng.py +0 -0
  336. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_scope.py +0 -0
  337. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_sources.py +0 -0
  338. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_spectrum.py +0 -0
  339. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_switch.py +0 -0
  340. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_table.py +0 -0
  341. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_wrapper.py +0 -0
  342. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/__init__.py +0 -0
  343. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_condition.py +0 -0
  344. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_event.py +0 -0
  345. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_schedule.py +0 -0
  346. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_zerocrossing.py +0 -0
  347. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/__init__.py +0 -0
  348. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_anderson.py +0 -0
  349. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_linearization.py +0 -0
  350. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_newton.py +0 -0
  351. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_numerical.py +0 -0
  352. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_operator.py +0 -0
  353. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/__init__.py +0 -0
  354. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/_referenceproblems.py +0 -0
  355. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_bdf.py +0 -0
  356. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_dirk2.py +0 -0
  357. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_dirk3.py +0 -0
  358. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk32.py +0 -0
  359. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk4.py +0 -0
  360. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk43.py +0 -0
  361. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk54.py +0 -0
  362. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk85.py +0 -0
  363. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_euler.py +0 -0
  364. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_gear.py +0 -0
  365. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rfk21.py +0 -0
  366. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rk4.py +0 -0
  367. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkbs32.py +0 -0
  368. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkck54.py +0 -0
  369. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkdp54.py +0 -0
  370. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkdp87.py +0 -0
  371. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkf45.py +0 -0
  372. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkf78.py +0 -0
  373. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkv65.py +0 -0
  374. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_solver.py +0 -0
  375. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk22.py +0 -0
  376. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk33.py +0 -0
  377. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk34.py +0 -0
  378. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_steadystate.py +0 -0
  379. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_auto_initial_step.py +0 -0
  380. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_checkpoint.py +0 -0
  381. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_connection.py +0 -0
  382. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_diagnostics.py +0 -0
  383. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_simulation_pss.py +0 -0
  384. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_subsystem.py +0 -0
  385. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/__init__.py +0 -0
  386. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_adaptivebuffer.py +0 -0
  387. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_analysis.py +0 -0
  388. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_fmuwrapper.py +0 -0
  389. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_gilbert.py +0 -0
  390. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_graph.py +0 -0
  391. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_logger.py +0 -0
  392. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_mutable.py +0 -0
  393. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_portreference.py +0 -0
  394. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_progresstracker.py +0 -0
  395. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_realtimeplotter.py +0 -0
  396. {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_register.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pathsim
3
- Version: 0.27.0
3
+ Version: 0.28.0
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
@@ -19,12 +19,12 @@ Requires-Dist: scipy>=1.2
19
19
  Provides-Extra: rf
20
20
  Requires-Dist: scikit-rf; extra == "rf"
21
21
  Provides-Extra: fmi
22
- Requires-Dist: FMPy; extra == "fmi"
22
+ Requires-Dist: FMPy>=0.3.22; extra == "fmi"
23
23
  Provides-Extra: test
24
24
  Requires-Dist: pytest; extra == "test"
25
25
  Requires-Dist: pytest-cov; extra == "test"
26
26
  Requires-Dist: pytest-xdist; extra == "test"
27
- Requires-Dist: FMPy; extra == "test"
27
+ Requires-Dist: FMPy>=0.3.22; extra == "test"
28
28
  Requires-Dist: scikit-rf; extra == "test"
29
29
  Dynamic: license-file
30
30
 
@@ -23,8 +23,8 @@ dependencies = ["numpy>=1.15", "matplotlib>=3.1", "scipy>=1.2"]
23
23
  # have moved to their own toolboxes (pathsim-rf, pathsim-fmi) and the extras
24
24
  # will be removed in v1.0.0. Install the toolboxes directly instead.
25
25
  rf = ["scikit-rf"]
26
- fmi = ["FMPy"]
27
- test = ["pytest", "pytest-cov", "pytest-xdist", "FMPy", "scikit-rf"]
26
+ fmi = ["FMPy>=0.3.22"]
27
+ test = ["pytest", "pytest-cov", "pytest-xdist", "FMPy>=0.3.22", "scikit-rf"]
28
28
 
29
29
  [project.urls]
30
30
  Homepage = "https://github.com/pathsim/pathsim"
@@ -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.27.0'
22
- __version_tuple__ = version_tuple = (0, 27, 0)
21
+ __version__ = version = '0.28.0'
22
+ __version_tuple__ = version_tuple = (0, 28, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g2cbb2f919'
24
+ __commit_id__ = commit_id = 'ge34add612'
@@ -8,13 +8,17 @@
8
8
  # IMPORTS ===============================================================================
9
9
 
10
10
  import numpy as np
11
+ import scipy.sparse as sp
11
12
 
12
13
  from scipy.linalg import lu_factor, lu_solve
13
14
 
14
15
  from ._block import Block
15
16
 
17
+ from ..utils.register import Register
18
+
16
19
  from ..optim.operator import DynamicOperator
17
- from ..optim.anderson import NewtonAnderson, solve_root
20
+ from ..optim.jacobian import NewtonOperator
21
+ from ..optim.anderson import NewtonAnderson, solve_root, _factorize_sparse
18
22
 
19
23
  from .._constants import SOL_TOLERANCE_FPI
20
24
 
@@ -51,7 +55,10 @@ class SemiExplicitDAE(Block):
51
55
  \\dot{x} = f_\\mathrm{dyn}(x, z(x, u, t), u, t)
52
56
 
53
57
  to the integration engine, so the DAE integrates with any solver, explicit
54
- or implicit. The block output is the stacked state :math:`[x, z]`.
58
+ or implicit. The block output is the stacked state :math:`[x, z]`, or
59
+ :math:`y = f_\\mathrm{out}(x, z, u, t)` if an output function is supplied.
60
+ Without algebraic states (empty `z0`) the block reduces to a plain ODE and
61
+ the constraint solve is skipped.
55
62
 
56
63
  Note
57
64
  ----
@@ -126,6 +133,9 @@ class SemiExplicitDAE(Block):
126
133
  convergence tolerance on the residual norm of the algebraic constraint
127
134
  solve, loosen it for ill-conditioned constraints whose residual cannot
128
135
  reach the default due to roundoff
136
+ func_out : callable, None
137
+ optional output function with signature `func_out(x, z, u, t)`, the
138
+ block output is the stacked state `[x, z]` if `None`
129
139
 
130
140
  Attributes
131
141
  ----------
@@ -148,7 +158,8 @@ class SemiExplicitDAE(Block):
148
158
  jac_dyn_x=None,
149
159
  jac_dyn_z=None,
150
160
  jac_alg_x=None,
151
- tolerance=SOL_TOLERANCE_FPI
161
+ tolerance=SOL_TOLERANCE_FPI,
162
+ func_out=None
152
163
  ):
153
164
 
154
165
  super().__init__()
@@ -157,6 +168,9 @@ class SemiExplicitDAE(Block):
157
168
  self.func_dyn = func_dyn
158
169
  self.func_alg = func_alg
159
170
 
171
+ #optional output function, stacked state [x, z] if 'None'
172
+ self.func_out = func_out
173
+
160
174
  #convergence tolerance of the algebraic constraint solve
161
175
  self.tolerance = tolerance
162
176
 
@@ -187,9 +201,10 @@ class SemiExplicitDAE(Block):
187
201
  self.op_dyn = DynamicOperator(func=self._rhs, jac_x=_jac_x)
188
202
 
189
203
  #pre-size the output register to the stacked state [x, z]
190
- self.outputs.update_from_array(
191
- np.concatenate([self.initial_value, self.z0])
192
- )
204
+ if self.func_out is None:
205
+ self.outputs.update_from_array(
206
+ np.concatenate([self.initial_value, self.z0])
207
+ )
193
208
 
194
209
 
195
210
  def __len__(self):
@@ -204,10 +219,11 @@ class SemiExplicitDAE(Block):
204
219
  """
205
220
  super().reset()
206
221
  self._z = self.z0.copy()
207
- x = self.engine.state if self.engine else self.initial_value
208
- self.outputs.update_from_array(
209
- np.concatenate([np.atleast_1d(x), self._z])
210
- )
222
+ if self.func_out is None:
223
+ x = self.engine.state if self.engine else self.initial_value
224
+ self.outputs.update_from_array(
225
+ np.concatenate([np.atleast_1d(x), self._z])
226
+ )
211
227
 
212
228
 
213
229
  def _solve_z(self, x, u, t):
@@ -229,6 +245,10 @@ class SemiExplicitDAE(Block):
229
245
  z : array[float]
230
246
  algebraic states satisfying the constraint
231
247
  """
248
+ #nothing to solve without algebraic states
249
+ if self._z.size == 0:
250
+ return self._z
251
+
232
252
  _func = lambda z: self.func_alg(x, z, u, t)
233
253
  _jac = None if self.jac_z is None else (lambda z: self.jac_z(x, z, u, t))
234
254
  z, _, _ = solve_root(self.opt, _func, self._z, _jac, tolerance=self.tolerance)
@@ -277,6 +297,8 @@ class SemiExplicitDAE(Block):
277
297
  """
278
298
  z = self._solve_z(x, u, t)
279
299
  fx = np.atleast_2d(self.jac_dyn_x(x, z, u, t))
300
+ if z.size == 0:
301
+ return fx
280
302
  fz = np.atleast_2d(self.jac_dyn_z(x, z, u, t))
281
303
  gx = np.atleast_2d(self.jac_alg_x(x, z, u, t))
282
304
  gz = np.atleast_2d(self.jac_z(x, z, u, t))
@@ -285,7 +307,7 @@ class SemiExplicitDAE(Block):
285
307
 
286
308
  def update(self, t):
287
309
  """Eliminate the algebraic states for the current input and expose the
288
- stacked state [x, z] at the output.
310
+ output function, or the stacked state [x, z], at the output.
289
311
 
290
312
  Parameters
291
313
  ----------
@@ -294,9 +316,11 @@ class SemiExplicitDAE(Block):
294
316
  """
295
317
  x, u = self.engine.state, self.inputs.to_array()
296
318
  self._z = self._solve_z(x, u, t)
297
- self.outputs.update_from_array(
298
- np.concatenate([np.atleast_1d(x), self._z])
299
- )
319
+ if self.func_out is None:
320
+ y = np.concatenate([np.atleast_1d(x), self._z])
321
+ else:
322
+ y = self.func_out(x, self._z, u, t)
323
+ self.outputs.update_from_array(y)
300
324
 
301
325
 
302
326
  def solve(self, t, dt):
@@ -608,14 +632,14 @@ class MassMatrixDAE(Block):
608
632
  def _res(xa):
609
633
  x = np.empty(self.mass.shape[0])
610
634
  x[self._d], x[self._a] = x_d, xa
611
- return self.func(x, u, t)[self._a]
635
+ return self.func(x, u, t)[self._a_equations]
612
636
 
613
637
  _jac = None
614
638
  if self.jac is not None:
615
639
  def _jac(xa):
616
640
  x = np.empty(self.mass.shape[0])
617
641
  x[self._d], x[self._a] = x_d, xa
618
- return np.atleast_2d(self.jac(x, u, t))[np.ix_(self._a, self._a)]
642
+ return np.atleast_2d(self.jac(x, u, t))[np.ix_(self._a_equations, self._a)]
619
643
 
620
644
  xa, _, _ = solve_root(self.opt, _res, self._xa, _jac, tolerance=self.tolerance)
621
645
  return xa
@@ -982,3 +1006,474 @@ class FullyImplicitDAE(Block):
982
1006
  x, u = self.engine.state, self.inputs.to_array()
983
1007
  self._xdot = self._solve_xdot(x, u, t)
984
1008
  return self.engine.step(self._xdot, dt)
1009
+
1010
+
1011
+ class SparseLinearDAE(Block):
1012
+ """Large sparse linear differential-algebraic equation (DAE) system.
1013
+
1014
+ Integrates the linear descriptor system
1015
+
1016
+ .. math::
1017
+
1018
+ \\begin{align}
1019
+ S_1 \\, x + S_2 \\, \\dot{x} &= B \\, u \\\\
1020
+ y &= C \\, x + D \\, u
1021
+ \\end{align}
1022
+
1023
+ where :math:`S_1`, :math:`S_2`, :math:`B`, :math:`C` and :math:`D` are ``scipy.sparse``
1024
+ matrices and :math:`S_2` is generally singular, so the algebraic rows
1025
+ (rows without derivatives) are constraints.
1026
+
1027
+ The system is never converted to a dense matrix. The nonzero rows
1028
+ :math:`S_{2,r}` of :math:`S_2` define the *differential states*
1029
+ :math:`d = S_{2,r}\\,x` (for a circuit these are the capacitor charges and
1030
+ the inductor fluxes) and with the embedding :math:`P` of these rows into the
1031
+ full system, :math:`S_2 = P\\,S_{2,r}`, the DAE becomes
1032
+
1033
+ .. math::
1034
+
1035
+ S_1\\,x + P\\,\\dot{d} = B\\,u, \\qquad S_{2,r}\\,x = d
1036
+
1037
+ which is the *constant sparse linear system*
1038
+
1039
+ .. math::
1040
+
1041
+ \\begin{bmatrix} S_1 & P \\\\ S_{2,r} & 0 \\end{bmatrix}
1042
+ \\begin{bmatrix} x \\\\ \\dot{d} \\end{bmatrix}
1043
+ =
1044
+ \\begin{bmatrix} B\\,u \\\\ d \\end{bmatrix}
1045
+
1046
+ that is factorized once with a sparse LU. Solving it yields the derivative
1047
+ :math:`\\dot{d}(d, u)` of the differential states and the full state
1048
+ :math:`x(d, u)`. So the block presents an ordinary explicit ODE in :math:`d`
1049
+ to the integration engine, which therefore works with any solver, explicit
1050
+ or implicit, including the adaptive ones, and the output
1051
+ :math:`y = C\\,x(d, u) + D\\,u` is evaluated algebraically.
1052
+
1053
+ The Jacobian :math:`\\partial \\dot{d} / \\partial d` of this reduction is
1054
+ dense (a Schur complement) and is never formed. It is handed to the
1055
+ implicit engines as a matrix-free :class:`.NewtonOperator` that solves the
1056
+ Newton system :math:`(c J - I)\\,y = r` of the :class:`.NewtonAnderson`
1057
+ optimizer with one sparse factorization of
1058
+
1059
+ .. math::
1060
+
1061
+ \\begin{bmatrix} S_1 & P \\\\ S_{2,r} & -c\\,I \\end{bmatrix}
1062
+
1063
+ per distinct scale :math:`c` (for a fixed timestep these repeat, so the
1064
+ factorizations are cached).
1065
+
1066
+ Note
1067
+ ----
1068
+ The reduction requires an index-1 system, which means that the matrix above
1069
+ has to be nonsingular. For circuits this excludes capacitor loops (for
1070
+ example parallel capacitors, or a capacitor directly across an ideal voltage
1071
+ source) and inductor cut-sets (for example inductors in series without a
1072
+ resistive path), where the charges / fluxes are not independent.
1073
+ Constructing the block raises a ``ValueError`` in these cases.
1074
+
1075
+ The differential states :math:`d` are scaled by the row norms of
1076
+ :math:`S_{2,r}`, so that they have the magnitude of the system variables
1077
+ (the rows of :math:`S_{2,r}` are normalized, :math:`P` carries the scale).
1078
+ This is an exact reformulation but matters numerically, since the
1079
+ tolerances of the implicit engines are absolute.
1080
+
1081
+ The initial condition ``initial_value`` is the initial value of these
1082
+ differential states, zero means no stored charge / flux, which is also the
1083
+ initial condition that `ElecSolver` assumes. Use ``x0`` to specify the
1084
+ initial condition as a full state instead.
1085
+
1086
+ Example
1087
+ -------
1088
+ An RC low-pass driven by a voltage source :math:`u`, with the unknowns
1089
+ :math:`x = [v_1, v_2, i]`:
1090
+
1091
+ .. code-block:: python
1092
+
1093
+ import numpy as np
1094
+ import scipy.sparse as sp
1095
+ from pathsim.blocks import SparseLinearDAE
1096
+
1097
+ R, C = 1e3, 1e-6
1098
+
1099
+ #v1 = u, v2 - v1 + R i = 0, C dv2/dt - i = 0
1100
+ S1 = sp.csr_matrix([[1., 0., 0.], [-1., 1., R], [0., 0., -1.]])
1101
+ S2 = sp.csr_matrix([[0., 0., 0.], [0., 0., 0.], [0., C, 0.]])
1102
+ B = sp.csr_matrix([[1.], [0.], [0.]])
1103
+
1104
+ rc = SparseLinearDAE(S1, S2, B, C=sp.csr_matrix([[0., 1., 0.]]))
1105
+
1106
+ Parameters
1107
+ ----------
1108
+ S1 : scipy.sparse matrix, shape (n, n)
1109
+ matrix of the non-differentiated states
1110
+ S2 : scipy.sparse matrix, shape (n, n)
1111
+ matrix of the differentiated states, may be singular
1112
+ B : scipy.sparse matrix, shape (n, nu)
1113
+ input matrix, one column per block input. For circuits with several
1114
+ sources this is the superposition of the unit sources, :math:`B\\,u =
1115
+ \\sum_k u_k b_k`
1116
+ C : scipy.sparse matrix, shape (ny, n), None
1117
+ output matrix, the full state :math:`y = x` is the output if `None`
1118
+ D : scipy.sparse matrix, shape (ny, nu), None
1119
+ direct feedthrough matrix from the inputs to the outputs, zero if `None`
1120
+ initial_value : array[float], None
1121
+ initial value of the differential states :math:`d`, zeros if `None`
1122
+ x0 : array[float], None
1123
+ initial condition as a full state, converted to :math:`d = S_{2,r}\\,x_0`,
1124
+ takes precedence over `initial_value`
1125
+ input_labels : list[str], None
1126
+ port aliases for the inputs
1127
+ output_labels : list[str], None
1128
+ port aliases for the outputs
1129
+
1130
+ Attributes
1131
+ ----------
1132
+ engine : Solver
1133
+ numerical integration engine for the differential states :math:`d`
1134
+ op_dyn : DynamicOperator
1135
+ dynamic operator of the reduced ODE :math:`\\dot{d}(d, u)`
1136
+ op_alg : DynamicOperator
1137
+ dynamic operator of the output :math:`y(d, u)`
1138
+ n : int
1139
+ number of states of the full system
1140
+ nd : int
1141
+ number of differential states
1142
+ """
1143
+
1144
+ #number of cached factorizations of the Newton system (distinct scales 'c')
1145
+ _NEWTON_CACHE = 8
1146
+
1147
+ def __init__(
1148
+ self,
1149
+ S1,
1150
+ S2,
1151
+ B,
1152
+ C=None,
1153
+ D=None,
1154
+ initial_value=None,
1155
+ x0=None,
1156
+ input_labels=None,
1157
+ output_labels=None
1158
+ ):
1159
+
1160
+ super().__init__()
1161
+
1162
+ #system matrices
1163
+ S1 = sp.csc_matrix(S1, dtype=float)
1164
+ S2 = sp.csr_matrix(S2, dtype=float)
1165
+ S2.eliminate_zeros()
1166
+ n = S1.shape[0]
1167
+
1168
+ if S1.shape != (n, n) or S2.shape != (n, n):
1169
+ raise ValueError(
1170
+ f"S1 and S2 must be square and equally sized but are {S1.shape}, {S2.shape}"
1171
+ )
1172
+
1173
+ B = sp.csr_matrix(B, dtype=float)
1174
+ if B.shape[0] != n:
1175
+ raise ValueError(f"B must have {n} rows but has {B.shape[0]}")
1176
+
1177
+ C = sp.identity(n, format="csr") if C is None else sp.csr_matrix(C, dtype=float)
1178
+ if C.shape[1] != n:
1179
+ raise ValueError(f"C must have {n} columns but has {C.shape[1]}")
1180
+
1181
+ self.n, self.nu, self.ny = n, B.shape[1], C.shape[0]
1182
+
1183
+ D = sp.csr_matrix((self.ny, self.nu)) if D is None else sp.csr_matrix(D, dtype=float)
1184
+ if D.shape != (self.ny, self.nu):
1185
+ raise ValueError(f"D must have shape {(self.ny, self.nu)} but has {D.shape}")
1186
+
1187
+ self.S1, self.S2, self.B, self.C, self.D = S1, S2, B, C, D
1188
+
1189
+ #differential states d = S2r x from the nonzero rows of S2
1190
+ rows = np.flatnonzero(np.diff(S2.indptr) > 0)
1191
+ nd = len(rows)
1192
+ if nd == 0:
1193
+ raise ValueError("S2 has no nonzero rows, the system has no dynamics")
1194
+
1195
+ self.nd = nd
1196
+
1197
+ #scale the differential states by the row norms of S2r, so they have the
1198
+ #magnitude of the system variables (e.g. volts and amps instead of coulombs
1199
+ #and webers, which can be many orders smaller). The optimizer tolerances of
1200
+ #the implicit engines are absolute, so badly scaled states converge too early.
1201
+ #This is an exact reformulation, S2 = P0 S2r = (P0 Dn) (Dn^-1 S2r)
1202
+ S2r = S2[rows]
1203
+ self._dscale = np.sqrt(np.asarray(S2r.multiply(S2r).sum(axis=1)).ravel())
1204
+ self._S2r = sp.diags(1.0 / self._dscale) @ S2r
1205
+ self._P = sp.csr_matrix((self._dscale, (rows, np.arange(nd))), shape=(n, nd))
1206
+
1207
+ #constant sparse system [[S1, P], [S2r, 0]] [x, dd] = [B u, d]
1208
+ K = sp.bmat([[S1, self._P], [self._S2r, None]], format="csc")
1209
+ self._lu = _factorize_sparse(K)
1210
+ if self._lu is None:
1211
+ raise ValueError(
1212
+ "the DAE is not index-1: the matrix [[S1, P], [S2r, 0]] is singular. "
1213
+ "For circuits: capacitor loops (e.g. parallel capacitors or a capacitor "
1214
+ "across an ideal voltage source) or inductor cut-sets (e.g. series "
1215
+ "inductors without a resistive path)."
1216
+ )
1217
+
1218
+ #factorizations of the newton system for different scales 'c'
1219
+ self._lu_newton = {}
1220
+
1221
+ #input dependence of the derivative and the output (dense, small: nu columns)
1222
+ _rhs = np.zeros((n + nd, self.nu))
1223
+ _rhs[:n] = B.toarray()
1224
+ _sol = self._lu.solve(_rhs) if self.nu else np.zeros((n + nd, 0))
1225
+ self._jac_u_dyn = _sol[n:]
1226
+ self._jac_u_alg = C @ _sol[:n] + D.toarray()
1227
+ self._feedthrough = bool(np.any(self._jac_u_alg != 0.0))
1228
+
1229
+ #lazily evaluated dense jacobian of the output w.r.t. the states
1230
+ self._jac_x_alg = None
1231
+
1232
+ #last solution of the sparse system, shared by dynamics and output
1233
+ self._cache = None
1234
+
1235
+ #initial condition of the differential states
1236
+ if x0 is not None:
1237
+ x0 = np.asarray(x0, dtype=float).ravel()
1238
+ if x0.size != n:
1239
+ raise ValueError(f"x0 must have {n} entries but has {x0.size}")
1240
+ initial_value = self._S2r @ x0
1241
+ self.initial_value = np.zeros(nd) if initial_value is None \
1242
+ else np.atleast_1d(initial_value).astype(float)
1243
+ if self.initial_value.size != nd:
1244
+ raise ValueError(
1245
+ f"initial_value must have {nd} entries (differential states) "
1246
+ f"but has {self.initial_value.size}"
1247
+ )
1248
+
1249
+ #matrix-free jacobian of the reduced ODE for the implicit engines
1250
+ self._jac = NewtonOperator(
1251
+ newton_solve=self._newton_solve,
1252
+ matvec=self._matvec,
1253
+ shape=(nd, nd)
1254
+ )
1255
+
1256
+ #operators for the reduced dynamics and the output
1257
+ self.op_dyn = DynamicOperator(
1258
+ func=self._func_dyn,
1259
+ jac_x=lambda x, u, t: self._jac,
1260
+ jac_u=lambda x, u, t: self._jac_u_dyn
1261
+ )
1262
+ self.op_alg = DynamicOperator(
1263
+ func=self._func_alg,
1264
+ jac_x=self._jac_alg_x,
1265
+ jac_u=lambda x, u, t: self._jac_u_alg
1266
+ )
1267
+
1268
+ #pre-sized, labeled ports
1269
+ self.inputs = Register(
1270
+ size=self.nu,
1271
+ mapping=None if input_labels is None else {k: i for i, k in enumerate(input_labels)}
1272
+ )
1273
+ self.outputs = Register(
1274
+ size=self.ny,
1275
+ mapping=None if output_labels is None else {k: i for i, k in enumerate(output_labels)}
1276
+ )
1277
+ self.outputs.update_from_array(
1278
+ self._func_alg(self.initial_value, np.zeros(self.nu), 0.0)
1279
+ )
1280
+
1281
+
1282
+ def __len__(self):
1283
+ """Algebraic passthrough from the inputs to the outputs exists if the
1284
+ output depends on the input directly, e.g. a node potential that is
1285
+ enforced by a voltage source.
1286
+ """
1287
+ return int(self._feedthrough) if self._active else 0
1288
+
1289
+
1290
+ # sparse solves -------------------------------------------------------------------
1291
+
1292
+ def _solve(self, d, u):
1293
+ """Solve the constant sparse system for the full state and the
1294
+ derivative of the differential states. The last solution is cached since
1295
+ the dynamics and the output are evaluated at the same point.
1296
+
1297
+ Parameters
1298
+ ----------
1299
+ d : array[float]
1300
+ differential states
1301
+ u : array[float]
1302
+ block input
1303
+
1304
+ Returns
1305
+ -------
1306
+ x : array[float]
1307
+ full state of the DAE
1308
+ dd : array[float]
1309
+ derivative of the differential states
1310
+ """
1311
+ d = np.atleast_1d(d)
1312
+ u = np.atleast_1d(u)
1313
+
1314
+ if u.size != self.nu:
1315
+ raise ValueError(
1316
+ f"'SparseLinearDAE' expects {self.nu} inputs but got {u.size}"
1317
+ )
1318
+
1319
+ if self._cache is not None \
1320
+ and np.array_equal(d, self._cache[0]) and np.array_equal(u, self._cache[1]):
1321
+ return self._cache[2]
1322
+
1323
+ sol = self._lu.solve(np.concatenate([self.B @ u, d]))
1324
+ res = sol[:self.n], sol[self.n:]
1325
+ self._cache = (d.copy(), u.copy(), res)
1326
+ return res
1327
+
1328
+
1329
+ def _func_dyn(self, x, u, t):
1330
+ """Reduced explicit ODE of the differential states."""
1331
+ return self._solve(x, u)[1]
1332
+
1333
+
1334
+ def _func_alg(self, x, u, t):
1335
+ """Output of the system."""
1336
+ return self.C @ self._solve(x, u)[0] + self.D @ np.atleast_1d(u)
1337
+
1338
+
1339
+ def _matvec(self, v):
1340
+ """Action of the reduced jacobian 'd(dd)/dd' on a vector."""
1341
+ sol = self._lu.solve(np.concatenate([np.zeros(self.n), v]))
1342
+ return sol[self.n:]
1343
+
1344
+
1345
+ def _newton_solve(self, c, r):
1346
+ """Solve the Newton system '(c J - I) y = r' for the reduced jacobian 'J'
1347
+ without forming it. With 'z = J y' this is 'c z - y = r', which together
1348
+ with the definition of 'J' is the sparse system
1349
+
1350
+ [[S1, P], [S2r, -c I]] [x, z] = [0, -r]
1351
+
1352
+ and then 'y = c z - r'.
1353
+
1354
+ Parameters
1355
+ ----------
1356
+ c : float
1357
+ scale of the jacobian (timestep times integrator coefficient)
1358
+ r : array[float]
1359
+ fixed-point residual
1360
+
1361
+ Returns
1362
+ -------
1363
+ y : array[float]
1364
+ solution of the Newton system
1365
+ """
1366
+ if c == 0.0:
1367
+ return -r
1368
+
1369
+ lu = self._lu_newton.get(c)
1370
+ if lu is None:
1371
+ Kc = sp.bmat(
1372
+ [[self.S1, self._P], [self._S2r, -c * sp.identity(self.nd)]],
1373
+ format="csc"
1374
+ )
1375
+ lu = _factorize_sparse(Kc)
1376
+ if lu is None:
1377
+ raise RuntimeError(
1378
+ f"the Newton matrix of 'SparseLinearDAE' is singular for scale {c}"
1379
+ )
1380
+ if len(self._lu_newton) >= self._NEWTON_CACHE:
1381
+ self._lu_newton.pop(next(iter(self._lu_newton)))
1382
+ self._lu_newton[c] = lu
1383
+
1384
+ z = lu.solve(np.concatenate([np.zeros(self.n), -r]))[self.n:]
1385
+ return c * z - r
1386
+
1387
+
1388
+ def _jac_alg_x(self, x, u, t):
1389
+ """Dense jacobian of the output w.r.t. the differential states, from
1390
+ 'ny' adjoint solves. Only needed for linearization, evaluated lazily.
1391
+ """
1392
+ if self._jac_x_alg is None:
1393
+ rhs = np.zeros((self.n + self.nd, self.ny))
1394
+ rhs[:self.n] = self.C.T.toarray()
1395
+ self._jac_x_alg = self._lu.solve(rhs, trans="T")[self.n:].T
1396
+ return self._jac_x_alg
1397
+
1398
+
1399
+ # block interface -----------------------------------------------------------------
1400
+
1401
+ def to_statespace(self, t):
1402
+ """Local linear state space model of the reduced system in the
1403
+ differential states :math:`d`, with dense matrices (the reduced system
1404
+ only has `nd` states).
1405
+
1406
+ Parameters
1407
+ ----------
1408
+ t : float
1409
+ evaluation time
1410
+
1411
+ Returns
1412
+ -------
1413
+ A, B, C, D : np.ndarray
1414
+ local state space matrices of the block
1415
+ """
1416
+ return (
1417
+ self._jac.toarray(),
1418
+ self._jac_u_dyn.copy(),
1419
+ self._jac_alg_x(None, None, t).copy(),
1420
+ self._jac_u_alg.copy()
1421
+ )
1422
+
1423
+
1424
+ def update(self, t):
1425
+ """Update the output, which algebraically depends on the differential
1426
+ states and the input.
1427
+
1428
+ Parameters
1429
+ ----------
1430
+ t : float
1431
+ evaluation time
1432
+ """
1433
+ x, u = self.engine.state, self.inputs.to_array()
1434
+ self.outputs.update_from_array(self.op_alg(x, u, t))
1435
+
1436
+
1437
+ def solve(self, t, dt):
1438
+ """Advance the implicit update equation of the solver with the reduced
1439
+ right hand side and its matrix-free Jacobian.
1440
+
1441
+ Parameters
1442
+ ----------
1443
+ t : float
1444
+ evaluation time
1445
+ dt : float
1446
+ integration timestep
1447
+
1448
+ Returns
1449
+ -------
1450
+ error : float
1451
+ solver residual norm
1452
+ """
1453
+ x, u = self.engine.state, self.inputs.to_array()
1454
+ f, J = self.op_dyn(x, u, t), self.op_dyn.jac_x(x, u, t)
1455
+ return self.engine.solve(f, J, dt)
1456
+
1457
+
1458
+ def step(self, t, dt):
1459
+ """Compute the timestep update with the integration engine.
1460
+
1461
+ Parameters
1462
+ ----------
1463
+ t : float
1464
+ evaluation time
1465
+ dt : float
1466
+ integration timestep
1467
+
1468
+ Returns
1469
+ -------
1470
+ success : bool
1471
+ step was successful
1472
+ error : float
1473
+ local truncation error from adaptive integrators
1474
+ scale : float
1475
+ timestep rescale from adaptive integrators
1476
+ """
1477
+ x, u = self.engine.state, self.inputs.to_array()
1478
+ f = self.op_dyn(x, u, t)
1479
+ return self.engine.step(f, dt)