physioblocks 1.0.3__tar.gz → 1.1.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.
- {physioblocks-1.0.3 → physioblocks-1.1.0}/PKG-INFO +1 -1
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/block_definition.rst +32 -106
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/__init__.py +1 -1
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/computing/models.py +313 -1
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/blocks/capacitances.py +28 -80
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/blocks/cavity.py +6 -24
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/blocks/valves.py +10 -37
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/model_components/active_law.py +37 -37
- physioblocks-1.1.0/tests/tests_computing/test_models.py +520 -0
- physioblocks-1.0.3/tests/tests_computing/test_models.py +0 -364
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.gitignore +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.gitlab/issue_templates/Bug.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.gitlab/issue_templates/Documentation.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.gitlab/issue_templates/Feature.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/.gitlab-ci.yml +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/README.md +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/.gitignore +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/Makefile +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/make.bat +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/base.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/computing.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/configuration.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/description.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/io.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/registers.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/simulation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference/utils.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/api_reference.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/conf.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/index.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/installation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/aliases/blocks.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/aliases/model_components.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/aliases/nets.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/aliases/simulation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/aliases.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/blocks.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/configuration/functions.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/configuration/net.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/configuration/simulation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/configuration.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/functions.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library/model_components.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/library.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/presentation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/assembling_example_scheme.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/circulation_net_scheme.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/circulation_net_scheme_heart.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/model_heart_circulation_0D.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/simple_circulation_model.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/simple_circulation_model_heart.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/schemes/spherical_heart_net_scheme.tex +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_1/launch_simulation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_1/launcher.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_1.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_2/aliases.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_2/create_net.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_2/create_simulation.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_2/overview.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_2.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/block_configuration.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/block_test.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/overview.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/specific_installations.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide.rst +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/docker/latex/Dockerfile +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/docker/pyenv/Dockerfile +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/licenses/GPL-3.0-only.txt +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/licenses/LGPL-3.0-only.txt +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/base/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/base/operators.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/base/registers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/computing/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/computing/assembling.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/computing/quantities.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/aliases.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/base.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/computing/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/computing/quantities.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/constants.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/description/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/description/blocks.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/description/nets.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/simulation/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/configuration/simulation/simulations.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/description/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/description/blocks.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/description/flux.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/description/nets.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/io/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/io/aliases.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/io/configuration.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/__main__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/configuration.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/configure/__main__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/constants.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/files.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/launcher/series.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/blocks/c_block.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/blocks/rc_block.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/blocks/rcr_block.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/blocks/spherical_cavity_block.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/blocks/valve_rl_block.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/model_components/rheology_fiber_additive.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/model_components/spherical_dynamics.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/model_components/velocity_law_hht.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/nets/circulation_alone_net.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/nets/spherical_heart_net.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/default_forward_simulation.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/default_time.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/newton_method_solver.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/blocks/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/base_operations.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/first_order.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/piecewise.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/trigonometric.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/functions/watchers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/model_components/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/model_components/dynamics.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/model_components/rheology.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/library/model_components/velocity_law.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/registers/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/registers/load_function_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/registers/save_function_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/registers/type_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/constants.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/runtime.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/saved_quantities.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/setup.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/solvers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/state.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/simulation/time_manager.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/utils/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/utils/dynamic_import_utils.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/utils/exceptions_utils.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/utils/gradient_test_utils.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/physioblocks/utils/math_utils.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/pyproject.toml +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/references/circulation_alone_sim.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/references/spherical_heart_respiration_sim.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/references/spherical_heart_sim.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/ruff.toml +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/base/test_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/helpers/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/helpers/assertion_helpers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/helpers/file_helpers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_computing/test_assembling.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_computing/test_quantities.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/test_definitions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/test_generic_save_load.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_alias/test_alias.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_description/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_description/test_config_blocks.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_description/test_config_boundary_condition.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_description/test_config_nets.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/simulation_reference.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/test_config_simulation.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/test_config_solvers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/test_config_time.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_config/tests_simulation/test_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_description/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_description/test_blocks.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_description/test_nets.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_description/test_relations.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/references/alt_config_file_path.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/references/commented_config_file_path.jsonc +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/references/configuration.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/test_aliases.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_io/test_configuration.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_blocks/test_capacitances.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_blocks/test_cavity.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_blocks/test_valves.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_functions/test_base_operations_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_functions/test_first_order_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_functions/test_piecewise_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_functions/test_trigonometric_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_functions/test_watch_functions.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_model_components/test_active_law.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_model_components/test_dynamics_block.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_model_components/test_rheology.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_library/tests_model_components/test_velocity_law_hht.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/circulation_alone/circulation_alone_sim_gradient_test.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/circulation_alone/ref_circulation_alone_sim.csv +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/conftest.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/io.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/spherical_heart/ref_spherical_heart_respiration_sim.csv +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/spherical_heart/ref_spherical_heart_sim.csv +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/spherical_heart/spherical_heart_sim_gradient_test.json +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/test_circulation_alone.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_references/test_spherical_heart.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_registers/test_load_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_registers/test_save_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_registers/test_type_register.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/__init__.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/test_runtime.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/test_setup.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/test_solvers.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/test_state.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_simulation/test_time_manager.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tests/tests_utils/test_math_utils.py +0 -0
- {physioblocks-1.0.3 → physioblocks-1.1.0}/tox.toml +0 -0
{physioblocks-1.0.3 → physioblocks-1.1.0}/doc/source/user_guide/level_3/block_definition.rst
RENAMED
|
@@ -185,10 +185,21 @@ Declare functions to compute the fluxes and the internal equations
|
|
|
185
185
|
|
|
186
186
|
We define methods to compute the :class:`~physioblocks.computing.models.Block` relations as written above in the discretized form.
|
|
187
187
|
|
|
188
|
+
To make the methods available to build the residual matrix the methods are decorated to identify:
|
|
189
|
+
|
|
190
|
+
* **Fluxes** with :func:`~physioblocks.computing.models.declares_flux` decorator.
|
|
191
|
+
You will need to set the local node index where the flux is shared as well as the local name in the block of the dof at the node.
|
|
192
|
+
The default flux size is 1 but can be updated.
|
|
193
|
+
* **Internal equations** with :func:`~physioblocks.computing.models.declares_internal_equation` decorator.
|
|
194
|
+
You need to set at least the local name of the variable on which the equation provides a dynamic.
|
|
195
|
+
Default equation size is set to 1 and can be updated.
|
|
196
|
+
|
|
197
|
+
|
|
188
198
|
.. code:: python
|
|
189
199
|
|
|
190
200
|
# Flux definition
|
|
191
201
|
|
|
202
|
+
@declares_flux(1, "pressure_1")
|
|
192
203
|
def flux_1(self):
|
|
193
204
|
"""
|
|
194
205
|
Computes the flux at first node.
|
|
@@ -198,6 +209,7 @@ We define methods to compute the :class:`~physioblocks.computing.models.Block` r
|
|
|
198
209
|
|
|
199
210
|
return (pressure_mid_discr - pressure_1_discr) / self.resistance_1.current
|
|
200
211
|
|
|
212
|
+
@declares_flux(2, "pressure_2")
|
|
201
213
|
def flux_2(self):
|
|
202
214
|
"""
|
|
203
215
|
Computes the flux at second node.
|
|
@@ -208,6 +220,7 @@ We define methods to compute the :class:`~physioblocks.computing.models.Block` r
|
|
|
208
220
|
return (pressure_mid_discr - pressure_2_discr) / self.resistance_2.current
|
|
209
221
|
|
|
210
222
|
# Internal Equation definition
|
|
223
|
+
@declares_internal_equation("pressure_mid")
|
|
211
224
|
def residual_pressure_mid(self):
|
|
212
225
|
"""
|
|
213
226
|
Computes the rcr block internal equation residual
|
|
@@ -222,7 +235,12 @@ We define methods to compute the :class:`~physioblocks.computing.models.Block` r
|
|
|
222
235
|
- (pressure_2_discr - pressure_mid_discr) / self.resistance_2
|
|
223
236
|
)
|
|
224
237
|
|
|
238
|
+
To be able to add output values that are not variables, we identify the saved quantities with :func:`~physioblocks.computing.models.declares_saved_quantity` decorator.
|
|
239
|
+
|
|
240
|
+
.. code:: python
|
|
241
|
+
|
|
225
242
|
# Saved Quantity definition
|
|
243
|
+
@declares_saved_quantities("volume")
|
|
226
244
|
def volume_stored(self):
|
|
227
245
|
"""
|
|
228
246
|
Computes volume stored in the capacitance.
|
|
@@ -234,17 +252,21 @@ Declare all flux and internal equations partial derivatives
|
|
|
234
252
|
|
|
235
253
|
We then have to declare functions to compute fluxes and internal equations partial derivatives.
|
|
236
254
|
|
|
237
|
-
|
|
255
|
+
To make the methods available to build the gradient matrix, the methods are decorated to identify function partial derivative with :func:`~physioblocks.computing.models.ExpressionDecorator.partial_derivative` decorator.
|
|
256
|
+
Each decorator associate the function with its the derivation variable local name.
|
|
238
257
|
|
|
239
|
-
|
|
258
|
+
.. code:: python
|
|
240
259
|
|
|
260
|
+
# Flux 1 partial derivatives
|
|
261
|
+
@flux_1.partial_derivative("pressure_mid")
|
|
241
262
|
def dflux_1_dpressure_mid(self):
|
|
242
263
|
"""
|
|
243
|
-
Computes flux_1 partial derivative for
|
|
264
|
+
Computes flux_1 partial derivative for pressure_mid.
|
|
244
265
|
"""
|
|
245
266
|
|
|
246
267
|
return 0.5 / self.resistance_1.current
|
|
247
268
|
|
|
269
|
+
@flux_1.partial_derivative("pressure_1")
|
|
248
270
|
def dflux_1_dpressure_1(self):
|
|
249
271
|
"""
|
|
250
272
|
Computes flux_1 partial derivative for pressure_1.
|
|
@@ -252,15 +274,17 @@ We then have to declare functions to compute fluxes and internal equations parti
|
|
|
252
274
|
|
|
253
275
|
return - 0.5 / self.resistance_1.current
|
|
254
276
|
|
|
255
|
-
# Flux
|
|
277
|
+
# Flux 2 partial derivatives
|
|
256
278
|
|
|
279
|
+
@flux_2.partial_derivative("pressure_mid")
|
|
257
280
|
def dflux_2_dpressure_mid(self):
|
|
258
281
|
"""
|
|
259
282
|
Computes flux_2 partial derivative for pressure_mid.
|
|
260
283
|
"""
|
|
261
284
|
|
|
262
|
-
return 0.5 / self.
|
|
285
|
+
return 0.5 / self.resistance_2.current
|
|
263
286
|
|
|
287
|
+
@flux_2.partial_derivative("pressure_2")
|
|
264
288
|
def dflux_2_dpressure_2(self):
|
|
265
289
|
"""
|
|
266
290
|
Computes flux_2 partial derivative for pressure_2.
|
|
@@ -270,6 +294,7 @@ We then have to declare functions to compute fluxes and internal equations parti
|
|
|
270
294
|
|
|
271
295
|
# Internal equation partial derivatives:
|
|
272
296
|
|
|
297
|
+
@residual_pressure_mid.partial_derivative("pressure_mid")
|
|
273
298
|
def dresidual_pressure_mid_dpressure_mid(self):
|
|
274
299
|
"""
|
|
275
300
|
Computes internal equation partial derivative for pressure_mid.
|
|
@@ -281,6 +306,7 @@ We then have to declare functions to compute fluxes and internal equations parti
|
|
|
281
306
|
+ 0.5 / self.resistance_2
|
|
282
307
|
)
|
|
283
308
|
|
|
309
|
+
@residual_pressure_mid.partial_derivative("pressure_1")
|
|
284
310
|
def dresidual_pressure_mid_dpressure_1(self):
|
|
285
311
|
"""
|
|
286
312
|
Computes internal equation partial derivative for pressure_1.
|
|
@@ -289,6 +315,7 @@ We then have to declare functions to compute fluxes and internal equations parti
|
|
|
289
315
|
- 0.5 / self.resistance_1
|
|
290
316
|
)
|
|
291
317
|
|
|
318
|
+
@residual_pressure_mid.partial_derivative("pressure_2")
|
|
292
319
|
def dresidual_pressure_mid_dpressure_2(self):
|
|
293
320
|
"""
|
|
294
321
|
Computes internal equation partial derivative for pressure_2.
|
|
@@ -297,107 +324,6 @@ We then have to declare functions to compute fluxes and internal equations parti
|
|
|
297
324
|
- 0.5 / self.resistance_2
|
|
298
325
|
)
|
|
299
326
|
|
|
300
|
-
Define the Block Expressions
|
|
301
|
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
302
|
-
|
|
303
|
-
We defined every method to compute our blocks relations along with the needed quantities.
|
|
304
|
-
But these methods are not yet available for the assembling process that builds the global system.
|
|
305
|
-
|
|
306
|
-
We will now declare **Flux**, **Internal Equations** and **Saved Quantities** :class:`~physioblocks.computing.models.Expression` objects to assemble a residual and gradient matrix.
|
|
307
|
-
|
|
308
|
-
This is performed on the **block type** directly, calling the created :class:`~physioblocks.library.blocks.capacitances.RCRBlock` class methods.
|
|
309
|
-
|
|
310
|
-
But first, we have to instantiate the :class:`~physioblocks.computing.models.Expression` objects.
|
|
311
|
-
They are composed of :
|
|
312
|
-
|
|
313
|
-
1. the **size** of the expression value
|
|
314
|
-
2. the **function** computing the expression value
|
|
315
|
-
3. a dictionary holding the **partial derivatives** for the function matched with the variable name.
|
|
316
|
-
|
|
317
|
-
Here are all the expressions needed for our :class:`~physioblocks.computing.models.Block`.
|
|
318
|
-
|
|
319
|
-
.. code:: python
|
|
320
|
-
|
|
321
|
-
# Define the flux expression going in the input node for rcr block
|
|
322
|
-
_rcr_block_flux_1_expr = Expression(
|
|
323
|
-
1, # flux 0 is size 1
|
|
324
|
-
RCRBlock.flux_1, # the function to compute flux 0
|
|
325
|
-
{
|
|
326
|
-
# the partial derivative for pressure 0 for flux 0
|
|
327
|
-
"pressure_1": RCRBlock.dflux_1_dpressure_1,
|
|
328
|
-
# the partial derivative for pressure mid for flux 0
|
|
329
|
-
"pressure_mid": RCRBlock.dflux_1_dpressure_mid,
|
|
330
|
-
}
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
# The next expressions are built similarly:
|
|
334
|
-
_rcr_block_flux_2_expr = Expression(
|
|
335
|
-
1,
|
|
336
|
-
RCRBlock.flux_2,
|
|
337
|
-
{
|
|
338
|
-
# the partial derivative for pressure 0 for flux 0
|
|
339
|
-
"pressure_2": RCRBlock.dflux_2_dpressure_2,
|
|
340
|
-
# the partial derivative for pressure mid for flux 0
|
|
341
|
-
"pressure_mid": RCRBlock.dflux_2_dpressure_mid,
|
|
342
|
-
}
|
|
343
|
-
)
|
|
344
|
-
|
|
345
|
-
_rcr_block_residual_expr = Expression(
|
|
346
|
-
1,
|
|
347
|
-
RCRBlock.residual_pressure_mid,
|
|
348
|
-
{
|
|
349
|
-
"pressure_mid": RCRBlock.dresidual_pressure_mid_dpressure_mid,
|
|
350
|
-
"pressure_1": RCRBlock.dresidual_pressure_mid_dpressure_1,
|
|
351
|
-
"pressure_2": RCRBlock.dresidual_pressure_mid_dpressure_2,
|
|
352
|
-
},
|
|
353
|
-
)
|
|
354
|
-
|
|
355
|
-
# The volume stored do not need partial derivatives
|
|
356
|
-
_rcr_block_volume_stored_expr = Expression(1, RCRBlock.volume_stored)
|
|
357
|
-
|
|
358
|
-
Now we use the :class:`~physioblocks.library.blocks.capacitances.RCRBlock` class methods to register the expressions.
|
|
359
|
-
To declare a flux expression for the block, we need:
|
|
360
|
-
|
|
361
|
-
1. the **index** of the local node sharing the flux.
|
|
362
|
-
2. the **variable local name** in the :class:`~physioblocks.computing.models.Block`.
|
|
363
|
-
3. the expression object
|
|
364
|
-
|
|
365
|
-
.. code:: python
|
|
366
|
-
|
|
367
|
-
RCRBlock.declares_flux_expression(
|
|
368
|
-
0,
|
|
369
|
-
"pressure_1",
|
|
370
|
-
_rcr_block_flux_1_expr
|
|
371
|
-
)
|
|
372
|
-
RCRBlock.declares_flux_expression(
|
|
373
|
-
1,
|
|
374
|
-
"pressure_2",
|
|
375
|
-
_rcr_block_flux_2_expr
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
To declare an internal equation expression for the block, we need:
|
|
380
|
-
|
|
381
|
-
1. the **internal variable local name** in the :class:`~physioblocks.computing.models.Block`
|
|
382
|
-
2. the expression object
|
|
383
|
-
|
|
384
|
-
.. code:: python
|
|
385
|
-
|
|
386
|
-
RCRBlock.declares_internal_expression(
|
|
387
|
-
"pressure_mid",
|
|
388
|
-
_rcr_block_residual_expr
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
Finally, to declare a **Saved Quantity** expression for the block, we need:
|
|
392
|
-
|
|
393
|
-
1. the saved quantity **local name**
|
|
394
|
-
2. the expression object
|
|
395
|
-
|
|
396
|
-
.. code:: python
|
|
397
|
-
|
|
398
|
-
RCRBlock.declares_saved_quantity_expression(
|
|
399
|
-
"volume_stored", _rcr_block_volume_stored_expr
|
|
400
|
-
)
|
|
401
327
|
|
|
402
328
|
Now the :class:`~physioblocks.library.blocks.capacitances.RCRBlock` is completely defined and can be used in a net.
|
|
403
329
|
|
|
@@ -32,6 +32,7 @@ functions.
|
|
|
32
32
|
|
|
33
33
|
from __future__ import annotations
|
|
34
34
|
|
|
35
|
+
import functools
|
|
35
36
|
from collections.abc import Callable
|
|
36
37
|
from dataclasses import dataclass, field
|
|
37
38
|
from inspect import get_annotations
|
|
@@ -46,7 +47,7 @@ SystemFunction: TypeAlias = Callable[..., np.float64 | NDArray[np.float64]]
|
|
|
46
47
|
"""Type alias for functions composing the system"""
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
@dataclass
|
|
50
|
+
@dataclass
|
|
50
51
|
class Expression:
|
|
51
52
|
"""Expression(size:int, expr_func: SystemFunction, expr_gradients: Mapping[str, SystemFunction] = {})
|
|
52
53
|
Store function computing numerical values for terms in the models with the function
|
|
@@ -102,6 +103,223 @@ class Expression:
|
|
|
102
103
|
)
|
|
103
104
|
|
|
104
105
|
|
|
106
|
+
class ExpressionDecorator:
|
|
107
|
+
"""
|
|
108
|
+
Base class for expression decorators.
|
|
109
|
+
|
|
110
|
+
This is a helper that defines expressions decorating methods in a model or block
|
|
111
|
+
class.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
expression: Expression
|
|
115
|
+
"""The expression resulting from decorators declarations"""
|
|
116
|
+
|
|
117
|
+
def __init__(
|
|
118
|
+
self,
|
|
119
|
+
wrapped_function: Callable[..., Any],
|
|
120
|
+
):
|
|
121
|
+
"""
|
|
122
|
+
:param wrapped_function: The decorated expression function
|
|
123
|
+
:type wrapped_function: Callable
|
|
124
|
+
"""
|
|
125
|
+
self.expression = Expression(0, wrapped_function)
|
|
126
|
+
self._terms: list[tuple[str, int, int]] = []
|
|
127
|
+
functools.update_wrapper(self, wrapped_function)
|
|
128
|
+
|
|
129
|
+
def register_term(
|
|
130
|
+
self,
|
|
131
|
+
term_name: str,
|
|
132
|
+
term_size: int,
|
|
133
|
+
term_index: int,
|
|
134
|
+
) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Register a new term to the expression decorator
|
|
137
|
+
|
|
138
|
+
:param term_name: the term local name.
|
|
139
|
+
:type term_name: str
|
|
140
|
+
|
|
141
|
+
:param term_size: The size of the term
|
|
142
|
+
:type term_size: int
|
|
143
|
+
|
|
144
|
+
:param term_index: The start index of the term in the expression
|
|
145
|
+
:type term_index: int
|
|
146
|
+
"""
|
|
147
|
+
self.expression.size += term_size
|
|
148
|
+
self._terms.append((term_name, term_size, term_index))
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def terms(self) -> list[tuple[str, int, int]]:
|
|
152
|
+
"""
|
|
153
|
+
Get the terms described by the expression.
|
|
154
|
+
|
|
155
|
+
:return: list of terms description
|
|
156
|
+
:rtype: list[[tuple[str, int, int]]]
|
|
157
|
+
"""
|
|
158
|
+
return self._terms.copy()
|
|
159
|
+
|
|
160
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
161
|
+
return self.expression.expr_func(*args, **kwargs)
|
|
162
|
+
|
|
163
|
+
def partial_derivative(
|
|
164
|
+
self, variable_name: str
|
|
165
|
+
) -> Callable[..., Callable[..., Any]]:
|
|
166
|
+
"""
|
|
167
|
+
Declares a flux partial derivative.
|
|
168
|
+
|
|
169
|
+
:param variable_name: the variable local name.
|
|
170
|
+
:type variable_name: str
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
def _register(wrapped: Callable[..., Any]) -> Callable[..., Any]:
|
|
174
|
+
self.expression.expr_gradients[variable_name] = wrapped
|
|
175
|
+
return wrapped
|
|
176
|
+
|
|
177
|
+
return _register
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _check_expression_decorator_type(
|
|
181
|
+
wrapped_function: Any, new_decorator_type: type[ExpressionDecorator]
|
|
182
|
+
) -> None:
|
|
183
|
+
if (
|
|
184
|
+
isinstance(wrapped_function, ExpressionDecorator) is True
|
|
185
|
+
and isinstance(wrapped_function, new_decorator_type) is False
|
|
186
|
+
):
|
|
187
|
+
raise ValueError(
|
|
188
|
+
str.format(
|
|
189
|
+
"Can not decorate a function of an other type. "
|
|
190
|
+
"Current type is {0}, new type is {1}.",
|
|
191
|
+
type(wrapped_function),
|
|
192
|
+
new_decorator_type,
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class InternalEquationDecorator(ExpressionDecorator):
|
|
198
|
+
"""
|
|
199
|
+
Define a decorator that identifies internal equation expressions.
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def declares_internal_equation(
|
|
206
|
+
variable_name: str, size: int = 1, starting_index: int = 0
|
|
207
|
+
) -> Callable[..., InternalEquationDecorator]:
|
|
208
|
+
"""
|
|
209
|
+
Declares a internal equation expression.
|
|
210
|
+
|
|
211
|
+
Once the internal equation function is declared, partial derivatives can be added
|
|
212
|
+
using the function name and the local variable name for the partial derivative.
|
|
213
|
+
|
|
214
|
+
:param variable_name: the variable name on which the expression provides a dynamic.
|
|
215
|
+
:type variable_name: str
|
|
216
|
+
|
|
217
|
+
:param size: the size of the equation. Default is 1
|
|
218
|
+
:type size: int
|
|
219
|
+
|
|
220
|
+
:param starting_index: the starting index of the equation line matching the
|
|
221
|
+
variable. Default is 0
|
|
222
|
+
:type starting_index: int
|
|
223
|
+
|
|
224
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
225
|
+
an expression decorator of an other type.
|
|
226
|
+
|
|
227
|
+
Example
|
|
228
|
+
^^^^^^^
|
|
229
|
+
|
|
230
|
+
.. code:: python
|
|
231
|
+
|
|
232
|
+
@dataclass
|
|
233
|
+
class SimpleModel(ModelComponent):
|
|
234
|
+
|
|
235
|
+
x: Quantity
|
|
236
|
+
a: Quantity
|
|
237
|
+
|
|
238
|
+
@declares_internal_equation("x")
|
|
239
|
+
def residual(self):
|
|
240
|
+
return x.new**2 - a.current
|
|
241
|
+
|
|
242
|
+
@flux_1.partial_derivative("x")
|
|
243
|
+
def dresidual_dx(self):
|
|
244
|
+
return 2.0 * x.new
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
def _create_internal_equation_decorator(
|
|
248
|
+
wrapped: Callable[..., Any],
|
|
249
|
+
) -> InternalEquationDecorator:
|
|
250
|
+
_check_expression_decorator_type(wrapped, InternalEquationDecorator)
|
|
251
|
+
|
|
252
|
+
decorated = (
|
|
253
|
+
wrapped
|
|
254
|
+
if isinstance(wrapped, InternalEquationDecorator)
|
|
255
|
+
else InternalEquationDecorator(wrapped)
|
|
256
|
+
)
|
|
257
|
+
decorated.register_term(variable_name, size, starting_index)
|
|
258
|
+
return decorated
|
|
259
|
+
|
|
260
|
+
return _create_internal_equation_decorator
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class SavedQuantityDecorator(ExpressionDecorator):
|
|
264
|
+
"""
|
|
265
|
+
Define a decorator that identifies saved quantities expressions.
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def declares_saved_quantity(
|
|
272
|
+
quantity_name: str, size: int = 1, starting_index: int = 0
|
|
273
|
+
) -> Callable[..., SavedQuantityDecorator]:
|
|
274
|
+
"""
|
|
275
|
+
Declares a saved quantity expression.
|
|
276
|
+
|
|
277
|
+
:param quantity_name: the local quantity name.
|
|
278
|
+
:type quantity_name: str
|
|
279
|
+
|
|
280
|
+
:param size: the size of the expression. Default is 1
|
|
281
|
+
:type size: int
|
|
282
|
+
|
|
283
|
+
:param starting_index: the starting index of the expression in the function.
|
|
284
|
+
Default is 0
|
|
285
|
+
:type starting_index: int
|
|
286
|
+
|
|
287
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
288
|
+
an expression decorator of an other type.
|
|
289
|
+
|
|
290
|
+
Example
|
|
291
|
+
^^^^^^^
|
|
292
|
+
|
|
293
|
+
.. code:: python
|
|
294
|
+
|
|
295
|
+
@dataclass
|
|
296
|
+
class SimpleModel(ModelComponent):
|
|
297
|
+
|
|
298
|
+
a: Quantity
|
|
299
|
+
b: Quantity
|
|
300
|
+
|
|
301
|
+
@declares_saved_quantity("a + b")
|
|
302
|
+
def sum(self):
|
|
303
|
+
return a.current + b.current
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
def _create_saved_quantity_decorator(
|
|
307
|
+
wrapped: Callable[..., Any],
|
|
308
|
+
) -> SavedQuantityDecorator:
|
|
309
|
+
_check_expression_decorator_type(wrapped, SavedQuantityDecorator)
|
|
310
|
+
|
|
311
|
+
decorator = (
|
|
312
|
+
wrapped
|
|
313
|
+
if isinstance(wrapped, SavedQuantityDecorator)
|
|
314
|
+
else SavedQuantityDecorator(wrapped)
|
|
315
|
+
)
|
|
316
|
+
decorator.register_term(quantity_name, size, starting_index)
|
|
317
|
+
|
|
318
|
+
return decorator
|
|
319
|
+
|
|
320
|
+
return _create_saved_quantity_decorator
|
|
321
|
+
|
|
322
|
+
|
|
105
323
|
@dataclass(frozen=True)
|
|
106
324
|
class TermDefinition:
|
|
107
325
|
"""Describe Terms defined in an :class:`~physioblocks.computing.models.Expression`.
|
|
@@ -303,6 +521,23 @@ class ModelComponentMetaClass(type):
|
|
|
303
521
|
cls.__INTERNAL_EXPRESSION_KEY: [],
|
|
304
522
|
cls.__SAVED_QUANTITIES_EXPRESSION_KEY: [],
|
|
305
523
|
}
|
|
524
|
+
for attr in cls.__dict__.values():
|
|
525
|
+
if isinstance(attr, InternalEquationDecorator):
|
|
526
|
+
for term_name, term_size, term_index in attr.terms:
|
|
527
|
+
cls.declares_internal_expression(
|
|
528
|
+
term_name,
|
|
529
|
+
attr.expression,
|
|
530
|
+
term_size,
|
|
531
|
+
term_index,
|
|
532
|
+
)
|
|
533
|
+
elif isinstance(attr, SavedQuantityDecorator):
|
|
534
|
+
for term_name, term_size, term_index in attr.terms:
|
|
535
|
+
cls.declares_saved_quantity_expression(
|
|
536
|
+
term_name,
|
|
537
|
+
attr.expression,
|
|
538
|
+
term_size,
|
|
539
|
+
term_index,
|
|
540
|
+
)
|
|
306
541
|
|
|
307
542
|
@staticmethod
|
|
308
543
|
def __is_quantity_type(type_to_test: Any) -> bool:
|
|
@@ -481,6 +716,7 @@ class ModelComponentMetaClass(type):
|
|
|
481
716
|
|
|
482
717
|
# Add the term definition to the expression definition
|
|
483
718
|
expression_def.terms.append(TermDefinition(term_id, size, index))
|
|
719
|
+
expression_def.terms.sort(key=lambda term: term.index)
|
|
484
720
|
|
|
485
721
|
def declares_internal_expression(
|
|
486
722
|
cls,
|
|
@@ -690,6 +926,78 @@ class ModelComponent(metaclass=ModelComponentMetaClass):
|
|
|
690
926
|
"""Override this method to define specific for model initialization."""
|
|
691
927
|
|
|
692
928
|
|
|
929
|
+
class FluxDecorator(ExpressionDecorator):
|
|
930
|
+
"""
|
|
931
|
+
Define a decorator that identifies flux functions
|
|
932
|
+
"""
|
|
933
|
+
|
|
934
|
+
pass
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
def declares_flux(
|
|
938
|
+
index: int, dof_name: str, size: int = 1
|
|
939
|
+
) -> Callable[..., FluxDecorator]:
|
|
940
|
+
"""
|
|
941
|
+
Declares a flux function.
|
|
942
|
+
|
|
943
|
+
Once the flux expression is declared, partial derivatives can be added using the
|
|
944
|
+
flux function name and the local variable name for the partial derivative.
|
|
945
|
+
|
|
946
|
+
:param index: the index of the flux in the block.
|
|
947
|
+
:type index: int
|
|
948
|
+
|
|
949
|
+
:param dof_name: the matching dof local name
|
|
950
|
+
:type dof_name: str
|
|
951
|
+
|
|
952
|
+
:param size: the size of the flux returned by the function
|
|
953
|
+
:type size: int
|
|
954
|
+
|
|
955
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
956
|
+
an expression decorator of an other type.
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
Example
|
|
960
|
+
^^^^^^^
|
|
961
|
+
|
|
962
|
+
.. code:: python
|
|
963
|
+
|
|
964
|
+
@dataclass
|
|
965
|
+
class SimpleBlock(Block):
|
|
966
|
+
|
|
967
|
+
q_1: Quantity
|
|
968
|
+
|
|
969
|
+
# declares a flux shared at local node 1, where the associated dof has the
|
|
970
|
+
# local name "potential_1"
|
|
971
|
+
@declares_flux(1, "potential_1")
|
|
972
|
+
def flux_1(self):
|
|
973
|
+
return q_1.new
|
|
974
|
+
|
|
975
|
+
# associate the following function as the partial derivative of "flux_1" for
|
|
976
|
+
# variable "q_1"
|
|
977
|
+
@flux_1.partial_derivative("q_1")
|
|
978
|
+
def dflux_1_dq_1(self):
|
|
979
|
+
return 1.0
|
|
980
|
+
|
|
981
|
+
"""
|
|
982
|
+
|
|
983
|
+
def _create_flux_decorator(wrapped: Callable[..., Any]) -> FluxDecorator:
|
|
984
|
+
if isinstance(wrapped, ExpressionDecorator) is True:
|
|
985
|
+
raise ValueError(
|
|
986
|
+
str.format(
|
|
987
|
+
"Function already declares an expression, it can not be a flux."
|
|
988
|
+
)
|
|
989
|
+
)
|
|
990
|
+
|
|
991
|
+
decorator = (
|
|
992
|
+
wrapped if isinstance(wrapped, FluxDecorator) else FluxDecorator(wrapped)
|
|
993
|
+
)
|
|
994
|
+
decorator.register_term(dof_name, size, index)
|
|
995
|
+
|
|
996
|
+
return decorator
|
|
997
|
+
|
|
998
|
+
return _create_flux_decorator
|
|
999
|
+
|
|
1000
|
+
|
|
693
1001
|
class BlockMetaClass(ModelComponentMetaClass):
|
|
694
1002
|
"""Meta-class for :class:`~physioblocks.computing.models.Block`.
|
|
695
1003
|
|
|
@@ -711,6 +1019,10 @@ class BlockMetaClass(ModelComponentMetaClass):
|
|
|
711
1019
|
def __init__(cls, *args: Any, **kwargs: Any) -> None:
|
|
712
1020
|
super().__init__(*args, **kwargs)
|
|
713
1021
|
cls._fluxes = {}
|
|
1022
|
+
for attr in cls.__dict__.values():
|
|
1023
|
+
if isinstance(attr, FluxDecorator):
|
|
1024
|
+
for term_name, _term_size, term_index in attr.terms:
|
|
1025
|
+
cls.declares_flux_expression(term_index, term_name, attr.expression)
|
|
714
1026
|
|
|
715
1027
|
def declares_flux_expression(
|
|
716
1028
|
cls, node_index: int, variable_id: str, expr: Expression
|