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.
- {pathsim-0.27.0 → pathsim-0.28.0}/PKG-INFO +3 -3
- {pathsim-0.27.0 → pathsim-0.28.0}/pyproject.toml +2 -2
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/_version.py +3 -3
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/dae.py +511 -16
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/delay.py +13 -4
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/__init__.py +1 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/anderson.py +89 -3
- pathsim-0.28.0/src/pathsim/optim/jacobian.py +144 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/operator.py +29 -3
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/simulation.py +4 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/PKG-INFO +3 -3
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/SOURCES.txt +4 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/requires.txt +2 -2
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/scm_file_list.json +4 -0
- pathsim-0.28.0/src/pathsim.egg-info/scm_version.json +8 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_dae.py +78 -1
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_delay.py +56 -1
- pathsim-0.28.0/tests/pathsim/blocks/test_delay_channels.py +64 -0
- pathsim-0.28.0/tests/pathsim/blocks/test_sparsedae.py +219 -0
- pathsim-0.28.0/tests/pathsim/optim/test_sparse_newton.py +264 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_simulation.py +85 -3
- pathsim-0.27.0/src/pathsim.egg-info/scm_version.json +0 -8
- {pathsim-0.27.0 → pathsim-0.28.0}/.codecov.yml +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.github/FUNDING.yml +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.github/pull_request_template.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/pypi_deployment.yml +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/tests_codecov.yml +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.github/workflows/urlchecker.yml +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/.gitignore +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/CITATION.cff +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/CONTRIBUTING.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/LICENSE.txt +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/README.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/conftest.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/abs_braking.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/algebraic_loop.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/billards.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/bouncing_ball.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/bouncing_pendulum.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/cascade_controller.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/checkpoints.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/chemical_reactor.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/coupled_oscillators.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/BouncingBall_ME.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/CoupledClutches_CS_linux64.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/CoupledClutches_CS_win64.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/Dahlquist.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/data/VanDerPol_ME.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/dcmotor_control.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/delta_sigma_adc.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/diode_circuit.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/elastic_pendulum.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/algebraicloop_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/billard_circle_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_both_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_events_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_ball_result_timesteps_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/bouncing_pendulum_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/cascade_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/coupled_oscillators_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/coupled_oscillators_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/delta_sigma_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/diode_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/elastic_pendulum_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/fmcw_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/fmcw_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/harmonic_oscillator_result_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/kalman_filter_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_result_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/linear_feedback_result_sensitivity_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/miller_frequency_divider_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/nonlinear_noisy_amplifier_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/ode_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/pendulum_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/pid_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/sar_adc_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_slip_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_blockdiagram_stick_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/stick_slip_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/thermostat_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_result_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl1_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl2_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/vanderpol_subsystem_lvl3_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/figures_g/volterralotka_blockdiagram_g.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/ode_blockdiagram_2.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/stick_slip_blockdiagram_slip.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/figures/stick_slip_blockdiagram_stick.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmcw_radar.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_cosimulation.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_model_exchange_bouncing_ball.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/fmu_model_exchange_vanderpol.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/harmonic_oscillator.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/kalman_filter.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/linear_feedback.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/lorenz_attractor.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/nested_subsystems.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/noisy_amplifier.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/pendulum.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/pid_controller.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/poincare_maps.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/rf_network_oneport.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/sar_adc.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/spectrum_analysis.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/stick_slip.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/switched_bouncing_ball.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/thermostat.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/transfer_function.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/examples/vanderpol.ipynb +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_icon.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_logo.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/logos/pathsim_simplistic_logo.png +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/docs/source/pathsim_docs.mplstyle +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_abs_braking.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_adc.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_algebraicchain.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_algebraicloop.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_cascade.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_dcmotor.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_deltasigma.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_derivative.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_diode.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_dualslope.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_elastic_pendulum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_feedback.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_filters.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_harmonic_oscillator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_kalman_filter.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_nested_subsystems.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_noise.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pendulum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_phasenoise.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid_antiwindup.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_pid_vs_discretePID.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_radar.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_reactor.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_sar.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_solar.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_solver_hotswap.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_spectrum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_spectrum_rf_oneport.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_steadystate.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_stickslip.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_transferfunction.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/example_vanderpol_subsystem.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_billards_sphere.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncing_pendulum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball_friction.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_bouncingball_switched.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_integrator_reset.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_pulse.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_stickslip_event.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_thermostat.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_event/example_volterralotka_event.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_bonhoeffer_vanderpol.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_brusselator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_chemical.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_duffing.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_fairen_velarde.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_fitzhughnagumo.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_flame.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_glycolysis.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_lorenz.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_morse.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_robertson.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_roessler.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_thomas_cyclic.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_vanderpol.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/examples/examples_odes/example_volterralotka.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/git +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/setup.cfg +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/_constants.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/README.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/_block.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/adder.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/amplifier.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/bvp.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/comparator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/constraint.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/converters.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/counter.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/ctrl.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/differentiator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/discrete.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/divider.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/dynsys.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/filters.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/fmu.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/function.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/integrator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/kalman.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/logic.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/lti.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/math.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/multiplier.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/noise.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/ode.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/relay.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/rf.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/rng.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/scope.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/sources.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/spectrum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/switch.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/table.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/blocks/wrapper.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/connection.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/_event.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/condition.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/schedule.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/events/zerocrossing.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/exceptions.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/booster.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/linearization.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/newton.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/optim/numerical.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/README.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/_rungekutta.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/_solver.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/bdf.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/dirk2.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/dirk3.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk32.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk4.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk43.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/esdirk85.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/euler.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/gear.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rk4.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkbs32.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkck54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkdp54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkdp87.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf21.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf45.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkf78.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/rkv65.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk22.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk33.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/ssprk34.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/solvers/steadystate.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/subsystem.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/adaptivebuffer.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/analysis.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/deprecation.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/diagnostics.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/fmuwrapper.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/gilbert.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/graph.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/logger.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/mutable.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/portreference.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/progresstracker.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/realtimeplotter.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim/utils/register.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/dependency_links.txt +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/src/pathsim.egg-info/top_level.txt +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/README.md +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/CoupledClutches_CS.fmu +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/conftest.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_algebraic_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_bouncingball_friction_event_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_bouncingball_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_brusselator_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_cosim_fmu_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_counter_comparator_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_dynamical_system_ivp.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_fitzhughnagumo_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_harmonic_oscillator_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_linear_feedback_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_logic_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_lorenz_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_me_analytical.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_model_exchange_fmu_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_pid_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_relay_thermostat_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_rescale_delay_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_robertson_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_roessler_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_signal_processing_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_steadystate_transient_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_switch_lti_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_vanderpol_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/evals/test_volterralotka_system.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/_embedding.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/ring_slot.s2p +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/ring_slot_meas.s1p +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/rf/test_rf.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_adder.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_amplifier.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_block.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_bvp.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_comparator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_constraint.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_converters.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_counter.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_ctrl.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_differentiator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_discrete.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_divider.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_dynsys.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_filters.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_fmu.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_function.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_integrator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_kalman.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_logic.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_lti.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_math.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_multiplier.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_noise.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_ode.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_relay.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_rng.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_scope.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_sources.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_spectrum.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_switch.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_table.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/blocks/test_wrapper.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_condition.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_event.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_schedule.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/events/test_zerocrossing.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_anderson.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_linearization.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_newton.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_numerical.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/optim/test_operator.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/_referenceproblems.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_bdf.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_dirk2.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_dirk3.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk32.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk4.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk43.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_esdirk85.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_euler.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_gear.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rfk21.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rk4.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkbs32.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkck54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkdp54.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkdp87.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkf45.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkf78.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_rkv65.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_solver.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk22.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk33.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_ssprk34.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/solvers/test_steadystate.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_auto_initial_step.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_checkpoint.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_connection.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_diagnostics.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_simulation_pss.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/test_subsystem.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/__init__.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_adaptivebuffer.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_analysis.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_fmuwrapper.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_gilbert.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_graph.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_logger.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_mutable.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_portreference.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_progresstracker.py +0 -0
- {pathsim-0.27.0 → pathsim-0.28.0}/tests/pathsim/utils/test_realtimeplotter.py +0 -0
- {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.
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.28.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 28, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
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.
|
|
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.
|
|
191
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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)
|