pathsim 0.27.1__tar.gz → 0.29.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.
- {pathsim-0.27.1 → pathsim-0.29.0}/PKG-INFO +3 -3
- {pathsim-0.27.1 → pathsim-0.29.0}/pyproject.toml +2 -2
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/__init__.py +1 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/_version.py +3 -3
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/__init__.py +1 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/_block.py +2 -34
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/dae.py +478 -3
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/delay.py +13 -4
- pathsim-0.29.0/src/pathsim/blocks/splitter.py +124 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/connection.py +31 -9
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/__init__.py +1 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/anderson.py +89 -3
- pathsim-0.29.0/src/pathsim/optim/jacobian.py +144 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/linearization.py +24 -8
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/operator.py +29 -3
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/simulation.py +24 -23
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/subsystem.py +10 -1
- pathsim-0.29.0/src/pathsim/utils/carrier.py +213 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/graph.py +7 -4
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/portreference.py +34 -10
- pathsim-0.29.0/src/pathsim/utils/register.py +298 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/PKG-INFO +3 -3
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/SOURCES.txt +10 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/requires.txt +2 -2
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/scm_file_list.json +10 -0
- pathsim-0.29.0/src/pathsim.egg-info/scm_version.json +8 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_dae.py +25 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_delay.py +56 -1
- pathsim-0.29.0/tests/pathsim/blocks/test_delay_channels.py +64 -0
- pathsim-0.29.0/tests/pathsim/blocks/test_sparsedae.py +219 -0
- pathsim-0.29.0/tests/pathsim/blocks/test_splitter.py +154 -0
- pathsim-0.29.0/tests/pathsim/optim/test_sparse_newton.py +264 -0
- pathsim-0.29.0/tests/pathsim/test_simulation_steadystate_recovery.py +94 -0
- pathsim-0.29.0/tests/pathsim/test_subsystem_current_inputs.py +63 -0
- pathsim-0.29.0/tests/pathsim/utils/test_carrier.py +365 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_register.py +19 -0
- pathsim-0.27.1/src/pathsim/utils/register.py +0 -190
- pathsim-0.27.1/src/pathsim.egg-info/scm_version.json +0 -8
- {pathsim-0.27.1 → pathsim-0.29.0}/.codecov.yml +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.github/FUNDING.yml +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.github/pull_request_template.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.github/workflows/pypi_deployment.yml +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.github/workflows/tests_codecov.yml +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.github/workflows/urlchecker.yml +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/.gitignore +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/CITATION.cff +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/CONTRIBUTING.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/LICENSE.txt +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/README.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/conftest.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/abs_braking.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/algebraic_loop.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/billards.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/bouncing_ball.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/bouncing_pendulum.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/cascade_controller.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/checkpoints.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/chemical_reactor.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/coupled_oscillators.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/data/BouncingBall_ME.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/data/CoupledClutches_CS_linux64.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/data/CoupledClutches_CS_win64.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/data/Dahlquist.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/data/VanDerPol_ME.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/dcmotor_control.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/delta_sigma_adc.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/diode_circuit.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/elastic_pendulum.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/algebraicloop_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/billard_circle_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_both_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_events_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_timesteps_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/bouncing_pendulum_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/cascade_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/coupled_oscillators_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/coupled_oscillators_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/delta_sigma_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/diode_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/elastic_pendulum_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/fmcw_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/fmcw_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_result_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/kalman_filter_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/linear_feedback_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/linear_feedback_result_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/linear_feedback_result_sensitivity_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/miller_frequency_divider_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/nonlinear_noisy_amplifier_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/ode_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/pendulum_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/pid_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/sar_adc_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_slip_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_stick_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/stick_slip_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/thermostat_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_result_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl1_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl2_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl3_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/figures_g/volterralotka_blockdiagram_g.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/ode_blockdiagram_2.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/stick_slip_blockdiagram_slip.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/figures/stick_slip_blockdiagram_stick.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/fmcw_radar.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/fmu_cosimulation.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/fmu_model_exchange_bouncing_ball.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/fmu_model_exchange_vanderpol.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/harmonic_oscillator.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/kalman_filter.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/linear_feedback.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/lorenz_attractor.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/nested_subsystems.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/noisy_amplifier.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/pendulum.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/pid_controller.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/poincare_maps.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/rf_network_oneport.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/sar_adc.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/spectrum_analysis.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/stick_slip.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/switched_bouncing_ball.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/thermostat.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/transfer_function.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/examples/vanderpol.ipynb +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/logos/pathsim_icon.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/logos/pathsim_logo.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/logos/pathsim_simplistic_logo.png +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/docs/source/pathsim_docs.mplstyle +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_abs_braking.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_adc.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_algebraicchain.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_algebraicloop.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_cascade.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_dcmotor.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_deltasigma.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_derivative.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_diode.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_dualslope.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_elastic_pendulum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_feedback.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_filters.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_harmonic_oscillator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_kalman_filter.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_nested_subsystems.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_noise.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_pendulum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_phasenoise.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_pid.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_pid_antiwindup.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_pid_vs_discretePID.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_radar.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_reactor.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_sar.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_solar.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_solver_hotswap.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_spectrum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_spectrum_rf_oneport.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_steadystate.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_stickslip.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_transferfunction.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/example_vanderpol_subsystem.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_billards_sphere.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_bouncing_pendulum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_bouncingball.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_bouncingball_friction.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_bouncingball_switched.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_integrator_reset.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_pulse.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_stickslip_event.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_thermostat.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_event/example_volterralotka_event.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_bonhoeffer_vanderpol.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_brusselator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_chemical.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_duffing.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_fairen_velarde.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_fitzhughnagumo.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_flame.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_glycolysis.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_lorenz.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_morse.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_robertson.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_roessler.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_thomas_cyclic.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_vanderpol.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/examples/examples_odes/example_volterralotka.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/git +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/setup.cfg +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/_constants.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/README.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/adder.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/amplifier.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/bvp.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/comparator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/constraint.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/converters.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/counter.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/ctrl.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/differentiator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/discrete.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/divider.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/dynsys.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/filters.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/fmu.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/function.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/integrator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/kalman.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/logic.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/lti.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/math.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/multiplier.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/noise.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/ode.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/relay.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/rf.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/rng.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/scope.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/sources.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/spectrum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/switch.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/table.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/blocks/wrapper.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/events/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/events/_event.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/events/condition.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/events/schedule.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/events/zerocrossing.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/exceptions.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/booster.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/newton.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/optim/numerical.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/README.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/_rungekutta.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/_solver.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/bdf.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/dirk2.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/dirk3.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/esdirk32.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/esdirk4.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/esdirk43.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/esdirk54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/esdirk85.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/euler.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/gear.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rk4.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkbs32.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkck54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkdp54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkdp87.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkf21.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkf45.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkf78.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/rkv65.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/ssprk22.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/ssprk33.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/ssprk34.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/solvers/steadystate.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/adaptivebuffer.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/analysis.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/deprecation.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/diagnostics.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/fmuwrapper.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/gilbert.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/logger.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/mutable.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/progresstracker.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim/utils/realtimeplotter.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/dependency_links.txt +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/src/pathsim.egg-info/top_level.txt +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/README.md +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/CoupledClutches_CS.fmu +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/conftest.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_algebraic_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_bouncingball_friction_event_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_bouncingball_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_brusselator_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_cosim_fmu_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_counter_comparator_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_dynamical_system_ivp.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_fitzhughnagumo_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_harmonic_oscillator_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_linear_feedback_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_logic_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_lorenz_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_me_analytical.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_model_exchange_fmu_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_pid_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_relay_thermostat_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_rescale_delay_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_robertson_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_roessler_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_signal_processing_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_steadystate_transient_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_switch_lti_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_vanderpol_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/evals/test_volterralotka_system.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/_embedding.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/rf/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/rf/ring_slot.s2p +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/rf/ring_slot_meas.s1p +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/rf/test_rf.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_adder.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_amplifier.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_block.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_bvp.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_comparator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_constraint.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_converters.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_counter.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_ctrl.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_differentiator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_discrete.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_divider.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_dynsys.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_filters.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_fmu.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_function.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_integrator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_kalman.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_logic.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_lti.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_math.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_multiplier.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_noise.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_ode.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_relay.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_rng.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_scope.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_sources.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_spectrum.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_switch.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_table.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/blocks/test_wrapper.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/events/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/events/test_condition.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/events/test_event.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/events/test_schedule.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/events/test_zerocrossing.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/test_anderson.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/test_linearization.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/test_newton.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/test_numerical.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/optim/test_operator.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/_referenceproblems.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_bdf.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_dirk2.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_dirk3.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_esdirk32.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_esdirk4.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_esdirk43.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_esdirk54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_esdirk85.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_euler.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_gear.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rfk21.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rk4.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkbs32.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkck54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkdp54.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkdp87.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkf45.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkf78.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_rkv65.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_solver.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_ssprk22.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_ssprk33.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_ssprk34.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/solvers/test_steadystate.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_auto_initial_step.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_checkpoint.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_connection.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_diagnostics.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_simulation.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_simulation_pss.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/test_subsystem.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/__init__.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_adaptivebuffer.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_analysis.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_fmuwrapper.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_gilbert.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_graph.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_logger.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_mutable.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_portreference.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_progresstracker.py +0 -0
- {pathsim-0.27.1 → pathsim-0.29.0}/tests/pathsim/utils/test_realtimeplotter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pathsim
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.29.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"
|
|
@@ -8,5 +8,6 @@ except Exception:
|
|
|
8
8
|
from .simulation import Simulation
|
|
9
9
|
from .connection import Connection, Duplex
|
|
10
10
|
from .subsystem import Subsystem, Interface
|
|
11
|
+
from .utils.carrier import Carrier, Vector
|
|
11
12
|
from .utils.logger import LoggerManager
|
|
12
13
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.29.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 29, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g220bc787c'
|
|
@@ -22,32 +22,6 @@ from ..optim.operator import DynamicOperator
|
|
|
22
22
|
from ..exceptions import LinearizationError
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
# HELPERS ===============================================================================
|
|
26
|
-
|
|
27
|
-
def _labels_size(labels):
|
|
28
|
-
"""Minimum register size required to hold all declared port labels.
|
|
29
|
-
|
|
30
|
-
Port labels map string aliases to integer port indices. The register has
|
|
31
|
-
to be large enough to address the highest declared index, otherwise blocks
|
|
32
|
-
with unconnected declared ports (e.g. a multi-input block placed without
|
|
33
|
-
connections) would default to the size 1 register and break positional
|
|
34
|
-
input access.
|
|
35
|
-
|
|
36
|
-
Parameters
|
|
37
|
-
----------
|
|
38
|
-
labels : dict[str: int] | None
|
|
39
|
-
port label mapping (alias -> index)
|
|
40
|
-
|
|
41
|
-
Returns
|
|
42
|
-
-------
|
|
43
|
-
size : int | None
|
|
44
|
-
minimum register size, or None if no labels are declared
|
|
45
|
-
"""
|
|
46
|
-
if not labels:
|
|
47
|
-
return None
|
|
48
|
-
return max(labels.values()) + 1
|
|
49
|
-
|
|
50
|
-
|
|
51
25
|
# BASE BLOCK CLASS ======================================================================
|
|
52
26
|
|
|
53
27
|
class Block:
|
|
@@ -123,14 +97,8 @@ class Block:
|
|
|
123
97
|
|
|
124
98
|
#registers to hold input and output values, pre-sized to the declared
|
|
125
99
|
#port labels so blocks with unconnected ports are still addressable
|
|
126
|
-
self.inputs = Register(
|
|
127
|
-
|
|
128
|
-
mapping=self.input_port_labels and self.input_port_labels.copy()
|
|
129
|
-
)
|
|
130
|
-
self.outputs = Register(
|
|
131
|
-
size=_labels_size(self.output_port_labels),
|
|
132
|
-
mapping=self.output_port_labels and self.output_port_labels.copy()
|
|
133
|
-
)
|
|
100
|
+
self.inputs = Register(mapping=self.input_port_labels)
|
|
101
|
+
self.outputs = Register(mapping=self.output_port_labels)
|
|
134
102
|
|
|
135
103
|
#initialize integration engine as 'None' by default
|
|
136
104
|
self.engine = None
|
|
@@ -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.
|
|
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
|
|
|
@@ -628,14 +632,14 @@ class MassMatrixDAE(Block):
|
|
|
628
632
|
def _res(xa):
|
|
629
633
|
x = np.empty(self.mass.shape[0])
|
|
630
634
|
x[self._d], x[self._a] = x_d, xa
|
|
631
|
-
return self.func(x, u, t)[self.
|
|
635
|
+
return self.func(x, u, t)[self._a_equations]
|
|
632
636
|
|
|
633
637
|
_jac = None
|
|
634
638
|
if self.jac is not None:
|
|
635
639
|
def _jac(xa):
|
|
636
640
|
x = np.empty(self.mass.shape[0])
|
|
637
641
|
x[self._d], x[self._a] = x_d, xa
|
|
638
|
-
return np.atleast_2d(self.jac(x, u, t))[np.ix_(self.
|
|
642
|
+
return np.atleast_2d(self.jac(x, u, t))[np.ix_(self._a_equations, self._a)]
|
|
639
643
|
|
|
640
644
|
xa, _, _ = solve_root(self.opt, _res, self._xa, _jac, tolerance=self.tolerance)
|
|
641
645
|
return xa
|
|
@@ -1002,3 +1006,474 @@ class FullyImplicitDAE(Block):
|
|
|
1002
1006
|
x, u = self.engine.state, self.inputs.to_array()
|
|
1003
1007
|
self._xdot = self._solve_xdot(x, u, t)
|
|
1004
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)
|
|
@@ -118,6 +118,9 @@ class Delay(Block):
|
|
|
118
118
|
|
|
119
119
|
#internal scheduled event for periodic sampling
|
|
120
120
|
def _sample(t):
|
|
121
|
+
#publish the delayed sample before evaluating the new input
|
|
122
|
+
if len(self._ring) > self._n:
|
|
123
|
+
self._ring.popleft()
|
|
121
124
|
self._sample_next_timestep = True
|
|
122
125
|
|
|
123
126
|
self.events = [
|
|
@@ -157,7 +160,12 @@ class Delay(Block):
|
|
|
157
160
|
npz_data.update(self._buffer.to_checkpoint(f"{prefix}/buffer"))
|
|
158
161
|
else:
|
|
159
162
|
#discrete mode: ring buffer
|
|
160
|
-
|
|
163
|
+
samples = list(self._ring)
|
|
164
|
+
if len(self.inputs) > 1:
|
|
165
|
+
#pad the initial scalar zeros and any narrower channel history
|
|
166
|
+
samples = [np.pad(np.atleast_1d(u), (0, len(self.inputs) - np.size(u)))
|
|
167
|
+
for u in samples]
|
|
168
|
+
npz_data[f"{prefix}/ring"] = np.array(samples)
|
|
161
169
|
json_data["_sample_next_timestep"] = self._sample_next_timestep
|
|
162
170
|
|
|
163
171
|
return json_data, npz_data
|
|
@@ -195,7 +203,7 @@ class Delay(Block):
|
|
|
195
203
|
self.outputs.update_from_array(y)
|
|
196
204
|
else:
|
|
197
205
|
#discrete mode: output the oldest value in the ring buffer
|
|
198
|
-
self.outputs
|
|
206
|
+
self.outputs.update_from_array(self._ring[0])
|
|
199
207
|
|
|
200
208
|
|
|
201
209
|
def sample(self, t, dt):
|
|
@@ -216,5 +224,6 @@ class Delay(Block):
|
|
|
216
224
|
else:
|
|
217
225
|
#discrete mode: only sample on scheduled events
|
|
218
226
|
if self._sample_next_timestep:
|
|
219
|
-
self.
|
|
220
|
-
self.
|
|
227
|
+
u = self.inputs[0] if len(self.inputs) == 1 else self.inputs.to_array()
|
|
228
|
+
self._ring.append(u)
|
|
229
|
+
self._sample_next_timestep = False
|