physioblocks 1.0.1__tar.gz → 1.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. {physioblocks-1.0.1 → physioblocks-1.0.3}/PKG-INFO +5 -2
  2. {physioblocks-1.0.1 → physioblocks-1.0.3}/README.md +4 -1
  3. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/aliases/simulation.rst +1 -1
  4. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/configuration/simulation.rst +7 -0
  5. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_2/create_simulation.rst +3 -3
  6. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3/block_test.rst +16 -4
  7. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/__init__.py +1 -1
  8. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/constants.py +2 -5
  9. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/simulation/simulations.py +11 -7
  10. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc +1 -3
  11. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/model_components/dynamics.py +4 -6
  12. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/runtime.py +1 -35
  13. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/solvers.py +34 -34
  14. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/state.py +67 -4
  15. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/utils/gradient_test_utils.py +11 -31
  16. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/test_config_simulation.py +3 -1
  17. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_blocks/test_capacitances.py +3 -9
  18. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_blocks/test_cavity.py +0 -3
  19. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_blocks/test_valves.py +5 -10
  20. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_model_components/test_active_law.py +1 -6
  21. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_model_components/test_dynamics_block.py +13 -10
  22. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_model_components/test_rheology.py +1 -3
  23. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_model_components/test_velocity_law_hht.py +1 -4
  24. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/test_circulation_alone.py +2 -2
  25. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/test_spherical_heart.py +2 -2
  26. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/test_solvers.py +41 -14
  27. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/test_state.py +87 -0
  28. {physioblocks-1.0.1 → physioblocks-1.0.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  29. {physioblocks-1.0.1 → physioblocks-1.0.3}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  30. {physioblocks-1.0.1 → physioblocks-1.0.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  31. {physioblocks-1.0.1 → physioblocks-1.0.3}/.gitignore +0 -0
  32. {physioblocks-1.0.1 → physioblocks-1.0.3}/.gitlab/issue_templates/Bug.md +0 -0
  33. {physioblocks-1.0.1 → physioblocks-1.0.3}/.gitlab/issue_templates/Documentation.md +0 -0
  34. {physioblocks-1.0.1 → physioblocks-1.0.3}/.gitlab/issue_templates/Feature.md +0 -0
  35. {physioblocks-1.0.1 → physioblocks-1.0.3}/.gitlab-ci.yml +0 -0
  36. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/.gitignore +0 -0
  37. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/Makefile +0 -0
  38. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/make.bat +0 -0
  39. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/base.rst +0 -0
  40. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/computing.rst +0 -0
  41. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/configuration.rst +0 -0
  42. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/description.rst +0 -0
  43. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/io.rst +0 -0
  44. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/registers.rst +0 -0
  45. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/simulation.rst +0 -0
  46. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference/utils.rst +0 -0
  47. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/api_reference.rst +0 -0
  48. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/conf.py +0 -0
  49. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/index.rst +0 -0
  50. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/installation.rst +0 -0
  51. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/aliases/blocks.rst +0 -0
  52. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/aliases/model_components.rst +0 -0
  53. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/aliases/nets.rst +0 -0
  54. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/aliases.rst +0 -0
  55. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/blocks.rst +0 -0
  56. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/configuration/functions.rst +0 -0
  57. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/configuration/net.rst +0 -0
  58. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/configuration.rst +0 -0
  59. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/functions.rst +0 -0
  60. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library/model_components.rst +0 -0
  61. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/library.rst +0 -0
  62. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/presentation.rst +0 -0
  63. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/assembling_example_scheme.tex +0 -0
  64. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/circulation_net_scheme.tex +0 -0
  65. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/circulation_net_scheme_heart.tex +0 -0
  66. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/model_heart_circulation_0D.tex +0 -0
  67. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/simple_circulation_model.tex +0 -0
  68. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/simple_circulation_model_heart.tex +0 -0
  69. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/schemes/spherical_heart_net_scheme.tex +0 -0
  70. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_1/launch_simulation.rst +0 -0
  71. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_1/launcher.rst +0 -0
  72. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_1.rst +0 -0
  73. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_2/aliases.rst +0 -0
  74. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_2/create_net.rst +0 -0
  75. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_2/overview.rst +0 -0
  76. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_2.rst +0 -0
  77. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3/block_configuration.rst +0 -0
  78. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3/block_definition.rst +0 -0
  79. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3/overview.rst +0 -0
  80. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3/specific_installations.rst +0 -0
  81. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide/level_3.rst +0 -0
  82. {physioblocks-1.0.1 → physioblocks-1.0.3}/doc/source/user_guide.rst +0 -0
  83. {physioblocks-1.0.1 → physioblocks-1.0.3}/docker/latex/Dockerfile +0 -0
  84. {physioblocks-1.0.1 → physioblocks-1.0.3}/docker/pyenv/Dockerfile +0 -0
  85. {physioblocks-1.0.1 → physioblocks-1.0.3}/licenses/GPL-3.0-only.txt +0 -0
  86. {physioblocks-1.0.1 → physioblocks-1.0.3}/licenses/LGPL-3.0-only.txt +0 -0
  87. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/base/__init__.py +0 -0
  88. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/base/operators.py +0 -0
  89. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/base/registers.py +0 -0
  90. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/computing/__init__.py +0 -0
  91. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/computing/assembling.py +0 -0
  92. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/computing/models.py +0 -0
  93. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/computing/quantities.py +0 -0
  94. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/__init__.py +0 -0
  95. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/aliases.py +0 -0
  96. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/base.py +0 -0
  97. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/computing/__init__.py +0 -0
  98. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/computing/quantities.py +0 -0
  99. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/description/__init__.py +0 -0
  100. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/description/blocks.py +0 -0
  101. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/description/nets.py +0 -0
  102. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/functions.py +0 -0
  103. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/configuration/simulation/__init__.py +0 -0
  104. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/description/__init__.py +0 -0
  105. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/description/blocks.py +0 -0
  106. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/description/flux.py +0 -0
  107. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/description/nets.py +0 -0
  108. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/io/__init__.py +0 -0
  109. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/io/aliases.py +0 -0
  110. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/io/configuration.py +0 -0
  111. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/__main__.py +0 -0
  112. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/configuration.py +0 -0
  113. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/configure/__main__.py +0 -0
  114. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/constants.py +0 -0
  115. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/files.py +0 -0
  116. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/launcher/series.py +0 -0
  117. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/__init__.py +0 -0
  118. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/blocks/c_block.json +0 -0
  119. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/blocks/rc_block.json +0 -0
  120. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/blocks/rcr_block.json +0 -0
  121. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/blocks/spherical_cavity_block.json +0 -0
  122. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/blocks/valve_rl_block.json +0 -0
  123. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc +0 -0
  124. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json +0 -0
  125. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/model_components/rheology_fiber_additive.json +0 -0
  126. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/model_components/spherical_dynamics.json +0 -0
  127. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/model_components/velocity_law_hht.json +0 -0
  128. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/nets/circulation_alone_net.json +0 -0
  129. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/nets/spherical_heart_net.json +0 -0
  130. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/default_forward_simulation.jsonc +0 -0
  131. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/default_time.jsonc +0 -0
  132. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/newton_method_solver.json +0 -0
  133. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc +0 -0
  134. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc +0 -0
  135. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/blocks/__init__.py +0 -0
  136. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/blocks/capacitances.py +0 -0
  137. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/blocks/cavity.py +0 -0
  138. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/blocks/valves.py +0 -0
  139. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/__init__.py +0 -0
  140. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/base_operations.py +0 -0
  141. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/first_order.py +0 -0
  142. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/piecewise.py +0 -0
  143. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/trigonometric.py +0 -0
  144. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/functions/watchers.py +0 -0
  145. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/model_components/__init__.py +0 -0
  146. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/model_components/active_law.py +0 -0
  147. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/model_components/rheology.py +0 -0
  148. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/library/model_components/velocity_law.py +0 -0
  149. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/registers/__init__.py +0 -0
  150. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/registers/load_function_register.py +0 -0
  151. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/registers/save_function_register.py +0 -0
  152. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/registers/type_register.py +0 -0
  153. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/__init__.py +0 -0
  154. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/constants.py +0 -0
  155. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/functions.py +0 -0
  156. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/saved_quantities.py +0 -0
  157. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/setup.py +0 -0
  158. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/simulation/time_manager.py +0 -0
  159. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/utils/__init__.py +0 -0
  160. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/utils/dynamic_import_utils.py +0 -0
  161. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/utils/exceptions_utils.py +0 -0
  162. {physioblocks-1.0.1 → physioblocks-1.0.3}/physioblocks/utils/math_utils.py +0 -0
  163. {physioblocks-1.0.1 → physioblocks-1.0.3}/pyproject.toml +0 -0
  164. {physioblocks-1.0.1 → physioblocks-1.0.3}/references/circulation_alone_sim.jsonc +0 -0
  165. {physioblocks-1.0.1 → physioblocks-1.0.3}/references/spherical_heart_respiration_sim.jsonc +0 -0
  166. {physioblocks-1.0.1 → physioblocks-1.0.3}/references/spherical_heart_sim.jsonc +0 -0
  167. {physioblocks-1.0.1 → physioblocks-1.0.3}/ruff.toml +0 -0
  168. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/__init__.py +0 -0
  169. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/base/test_register.py +0 -0
  170. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/helpers/__init__.py +0 -0
  171. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/helpers/assertion_helpers.py +0 -0
  172. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/helpers/file_helpers.py +0 -0
  173. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_computing/test_assembling.py +0 -0
  174. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_computing/test_models.py +0 -0
  175. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_computing/test_quantities.py +0 -0
  176. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/__init__.py +0 -0
  177. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/test_definitions.py +0 -0
  178. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/test_generic_save_load.py +0 -0
  179. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_alias/test_alias.py +0 -0
  180. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_description/__init__.py +0 -0
  181. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_description/test_config_blocks.py +0 -0
  182. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_description/test_config_boundary_condition.py +0 -0
  183. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_description/test_config_nets.py +0 -0
  184. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/__init__.py +0 -0
  185. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/simulation_reference.json +0 -0
  186. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/test_config_solvers.py +0 -0
  187. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/test_config_time.py +0 -0
  188. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_config/tests_simulation/test_functions.py +0 -0
  189. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_description/__init__.py +0 -0
  190. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_description/test_blocks.py +0 -0
  191. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_description/test_nets.py +0 -0
  192. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_description/test_relations.py +0 -0
  193. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/__init__.py +0 -0
  194. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/references/alt_config_file_path.json +0 -0
  195. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/references/commented_config_file_path.jsonc +0 -0
  196. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/references/configuration.json +0 -0
  197. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/test_aliases.py +0 -0
  198. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_io/test_configuration.py +0 -0
  199. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_functions/test_base_operations_functions.py +0 -0
  200. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_functions/test_first_order_functions.py +0 -0
  201. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_functions/test_piecewise_functions.py +0 -0
  202. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_functions/test_trigonometric_functions.py +0 -0
  203. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_library/tests_functions/test_watch_functions.py +0 -0
  204. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/__init__.py +0 -0
  205. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/circulation_alone/circulation_alone_sim_gradient_test.json +0 -0
  206. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/circulation_alone/ref_circulation_alone_sim.csv +0 -0
  207. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/conftest.py +0 -0
  208. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/io.py +0 -0
  209. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/spherical_heart/ref_spherical_heart_respiration_sim.csv +0 -0
  210. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/spherical_heart/ref_spherical_heart_sim.csv +0 -0
  211. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_references/spherical_heart/spherical_heart_sim_gradient_test.json +0 -0
  212. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_registers/test_load_register.py +0 -0
  213. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_registers/test_save_register.py +0 -0
  214. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_registers/test_type_register.py +0 -0
  215. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/__init__.py +0 -0
  216. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/test_runtime.py +0 -0
  217. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/test_setup.py +0 -0
  218. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_simulation/test_time_manager.py +0 -0
  219. {physioblocks-1.0.1 → physioblocks-1.0.3}/tests/tests_utils/test_math_utils.py +0 -0
  220. {physioblocks-1.0.1 → physioblocks-1.0.3}/tox.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: physioblocks
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Dynamic: Author
5
5
  Dynamic: Author-email
6
6
  Dynamic: License
@@ -124,4 +124,7 @@ python -m physioblocks.launcher references/spherical_heart_sim.jsonc -v -t -s Qu
124
124
  ```
125
125
 
126
126
 
127
- Results will be available in the `$LAUNCHER_FOLDER_PATH$/simulations/QuickStart` series folder.
127
+ Results will be available in the `$LAUNCHER_FOLDER_PATH$/simulations/QuickStart` series folder:
128
+ * the csv file contains the simulation results.
129
+ * the html allows you to visualize the results.
130
+ * the log and json files are here for debug purposes.
@@ -76,4 +76,7 @@ python -m physioblocks.launcher references/spherical_heart_sim.jsonc -v -t -s Qu
76
76
  ```
77
77
 
78
78
 
79
- Results will be available in the `$LAUNCHER_FOLDER_PATH$/simulations/QuickStart` series folder.
79
+ Results will be available in the `$LAUNCHER_FOLDER_PATH$/simulations/QuickStart` series folder:
80
+ * the csv file contains the simulation results.
81
+ * the html allows you to visualize the results.
82
+ * the log and json files are here for debug purposes.
@@ -94,7 +94,7 @@ Parameters
94
94
  * ``proximal``: blood flow boundary condition
95
95
  * ``venous``: blood pressure boundary condition
96
96
 
97
- * Sets default parameters, magnitudes. Especially:
97
+ * Sets default parameters, variables and magnitudes. Especially:
98
98
 
99
99
  * ``aorta_proximal.blood_flow`` is a periodic function needing a min and max value.
100
100
  * ``heart_rate`` parameter is introduced to set the function periodicity.
@@ -133,6 +133,13 @@ Solvers Configuration
133
133
 
134
134
  Description of available configuration item to build :class:`~physioblocks.simulation.solvers.AbstractSolver` object from a configuration file.
135
135
 
136
+
137
+ Linear Solver
138
+ -------------
139
+
140
+ * **Class:** :class:`~physioblocks.simulation.solvers.LinearSolver`
141
+ * **Type name:** ``linear_solver``
142
+
136
143
  Newton Solver
137
144
  -------------
138
145
 
@@ -89,8 +89,7 @@ Solver
89
89
 
90
90
  This field define the solver implementation used to run a single simulation step.
91
91
 
92
- For now, only the :class:`~physioblocks.simulation.solvers.NewtonSolver` object is implemented in the current API.
93
- Its ``type`` is found in the :ref:`configuration section <library_configuration_simulation_solvers>` of the library
92
+ The ``type`` parameters of available solver are found in the :ref:`configuration section <library_configuration_simulation_solvers>` of the library.
94
93
 
95
94
  .. code:: json
96
95
 
@@ -111,6 +110,7 @@ In this case, we set two parameters to the solver:
111
110
  Concerning our simple example the problem is **linear**, so a **Newton method is not adapted**.
112
111
  Still, we should be able to solve the system in two iterations, so ``iteration_max`` is set to 2.
113
112
 
113
+ A better choice would have been the ``linear_solver``, but we wanted to show the Newton solver in the example because it will be useful for most nets.
114
114
 
115
115
  Time
116
116
  ^^^^
@@ -135,7 +135,7 @@ It needs :
135
135
  }
136
136
 
137
137
  Here we set a 30 seconds simulation starting at 0.0.
138
- The simulation gives the state each 1ms and can divide a time step in parts of minimum lenght 62.5us before considering it can not solve the global system for the step.
138
+ The simulation gives the state each 1ms and can divide a time step in parts of minimum length 62.5us before considering it can not solve the global system for the step.
139
139
 
140
140
  Net
141
141
  ^^^
@@ -144,10 +144,16 @@ Let's see an example for the RCR Block:
144
144
  state["pressure_2"] = ref_block.pressure_2
145
145
 
146
146
  # Provide the variables magnitudes
147
- magnitudes = np.array([1e4, 1e4, 1e4])
147
+ state.set_variables_magnitudes(
148
+ {
149
+ "pressure_1": 1e4,
150
+ "pressure_mid": 1e4,
151
+ "pressure_2": 1e4,
152
+ }
153
+ )
148
154
 
149
155
  # call the test function
150
- assert gradient_test_from_model(ref_rcr_block, state, magnitudes)
156
+ assert gradient_test_from_model(ref_rcr_block, state)
151
157
 
152
158
 
153
159
  Test a single expression
@@ -182,7 +188,13 @@ From our previous example, let's only test the flux at node 0:
182
188
  state["pressure_2"] = ref_block.pressure_2
183
189
 
184
190
  # Provide the variables magnitude
185
- magnitudes = np.array([1e4, 1e4, 1e4])
191
+ state.set_variables_magnitudes(
192
+ {
193
+ "pressure_1": 1e4,
194
+ "pressure_mid": 1e4,
195
+ "pressure_2": 1e4,
196
+ }
197
+ )
186
198
 
187
199
  # call the test function
188
- assert gradient_test_from_expression(RCRBlock.fluxes_expressions[0].expression, state, magnitudes)
200
+ assert gradient_test_from_expression(RCRBlock.fluxes_expressions[0].expression, state)
@@ -26,7 +26,7 @@
26
26
 
27
27
  """Physioblocks package definition"""
28
28
 
29
- __version__ = "1.0.1"
29
+ __version__ = "1.0.3"
30
30
  __copyright__ = "INRIA"
31
31
  __license__ = "LGPL-3.0-only"
32
32
  __authors__ = [
@@ -38,11 +38,8 @@ PARAMETERS_ID = "parameters"
38
38
  # Definition of the flux-dof types couples
39
39
  FLUX_DOF_DEFINITION_ID = "flux_dof_definitions"
40
40
 
41
-
42
- # Magnitudes
43
-
44
- # The variable magnitude item label in the configuration
45
- MAGNITUDES = "magnitudes"
41
+ # Options label for specific simulation types
42
+ SIMULATION_OPTIONS = "simulation_options"
46
43
 
47
44
  # The variable magnitude item label in the configuration
48
45
  VARIABLES_MAGNITUDES = "variables_magnitudes"
@@ -35,10 +35,10 @@ from typing import Any
35
35
  from physioblocks.configuration.base import Configuration, ConfigurationError
36
36
  from physioblocks.configuration.constants import (
37
37
  INIT_VARIABLES_ID,
38
- MAGNITUDES,
39
38
  NET_ID,
40
39
  OUTPUTS_FUNCTIONS_ID,
41
40
  PARAMETERS_ID,
41
+ SIMULATION_OPTIONS,
42
42
  SOLVER_ID,
43
43
  TIME_MANAGER_ID,
44
44
  VARIABLES_MAGNITUDES,
@@ -86,16 +86,15 @@ def load_simulation_config(
86
86
  if SOLVER_ID in config:
87
87
  solver = load(config[SOLVER_ID])
88
88
 
89
- # magnitudes
90
- magnitudes = None
91
- if VARIABLES_MAGNITUDES in config:
92
- magnitudes = load(config[VARIABLES_MAGNITUDES])
89
+ simulation_options = None
90
+ if SIMULATION_OPTIONS in config:
91
+ simulation_options = load(config[SIMULATION_OPTIONS])
93
92
 
94
93
  sim_factory = SimulationFactory(
95
94
  configuration_type,
96
95
  solver,
97
96
  net,
98
- simulation_options={MAGNITUDES: magnitudes},
97
+ simulation_options=simulation_options,
99
98
  )
100
99
 
101
100
  configuration_object = sim_factory.create_simulation()
@@ -147,7 +146,7 @@ def save_simulation_config(
147
146
  type(variable_init_values).__name__,
148
147
  )
149
148
  )
150
- sim_config[VARIABLES_MAGNITUDES] = save(simulation.magnitudes)
149
+ sim_config[VARIABLES_MAGNITUDES] = save(simulation.state.magnitudes)
151
150
 
152
151
  # Parameters
153
152
  # Get quantities
@@ -226,6 +225,11 @@ def _configure_simulation(
226
225
  configuration_references=simulation.quantities,
227
226
  )
228
227
 
228
+ # magnitudes
229
+ if VARIABLES_MAGNITUDES in config:
230
+ magnitudes = load(config[VARIABLES_MAGNITUDES])
231
+ simulation.state.set_variables_magnitudes(magnitudes)
232
+
229
233
  references.update(simulation.quantities)
230
234
  references.update(simulation.models)
231
235
 
@@ -49,7 +49,5 @@
49
49
  "inverses": ["aorta_distal.resistance"]
50
50
  }
51
51
  },
52
- "solver": {
53
- "iteration_max": 2 // This problem is linear
54
- }
52
+ "solver": {"type": "linear_solver"}
55
53
  }
@@ -902,7 +902,9 @@ class SphericalDynamicsModelComponent(ModelComponent):
902
902
  eq_system = EqSystem(1)
903
903
 
904
904
  state = State()
905
- state.add_variable(SPHERICAL_DYNAMICS_STATIC_DISP_LOCAL_ID, 1)
905
+ state.add_variable(
906
+ SPHERICAL_DYNAMICS_STATIC_DISP_LOCAL_ID, 1, _STATIC_PROBLEM_DISP_MAG
907
+ )
906
908
  state[SPHERICAL_DYNAMICS_STATIC_DISP_LOCAL_ID].initialize(self.disp.current)
907
909
 
908
910
  static_block = _SphericalDynamicsStaticModelComponent(
@@ -942,11 +944,7 @@ class SphericalDynamicsModelComponent(ModelComponent):
942
944
  p_test <= static_block.pressure.current
943
945
  and p_test > _STATIC_PROBLEM_MIN_PRESSURE_STEP
944
946
  ):
945
- sol = solver.solve(
946
- state,
947
- eq_system,
948
- {SPHERICAL_DYNAMICS_STATIC_DISP_LOCAL_ID: _STATIC_PROBLEM_DISP_MAG},
949
- )
947
+ sol = solver.solve(state, eq_system)
950
948
 
951
949
  if sol.converged is True:
952
950
  state[SPHERICAL_DYNAMICS_STATIC_DISP_LOCAL_ID].initialize(sol.x[0])
@@ -96,9 +96,6 @@ class AbstractSimulation(ABC):
96
96
 
97
97
  :param eq_system: the equation system to solve at each time step
98
98
  :type eq_system: EqSystem
99
-
100
- :param magnitudes: magnitude of the state variables
101
- :type magnitudes: dict[str, float]
102
99
  """
103
100
 
104
101
  def __init__(
@@ -111,7 +108,6 @@ class AbstractSimulation(ABC):
111
108
  models: dict[str, ModelComponent],
112
109
  solver: AbstractSolver,
113
110
  eq_system: EqSystem,
114
- magnitudes: dict[str, float] | None = None,
115
111
  ):
116
112
  self.factory = factory
117
113
  self.state = state
@@ -121,9 +117,6 @@ class AbstractSimulation(ABC):
121
117
  self.time_manager = time_manager
122
118
  self.solver = solver
123
119
  self.eq_system = eq_system
124
- if magnitudes is None:
125
- magnitudes = {}
126
- self.magnitudes = self._check_magnitudes(magnitudes, state)
127
120
  self._timed_updates: dict[str, AbstractFunction] = {}
128
121
  self._output_functions_updates: dict[str, AbstractFunction] = {}
129
122
 
@@ -272,33 +265,6 @@ class AbstractSimulation(ABC):
272
265
  self.time_manager.time.initialize(self.time_manager.start)
273
266
  self.state.set_state_vector(self._initial_state)
274
267
 
275
- def _check_magnitudes(
276
- self, magnitudes: dict[str, float], state: State
277
- ) -> dict[str, float]:
278
- checked_magnitudes = {}
279
-
280
- for variable_id in state:
281
- if variable_id not in magnitudes:
282
- message = str.format(
283
- "No magnitude initialized for variable {0}. Magnitude set to 1.0",
284
- variable_id,
285
- )
286
- _logger.warning(message)
287
- checked_magnitudes[variable_id] = 1.0
288
-
289
- elif magnitudes[variable_id] == 0.0:
290
- message = str.format(
291
- "Magnitude for variable {0} is initialized to 0.0. "
292
- "Replacing with 1.0",
293
- variable_id,
294
- )
295
- _logger.warning(message)
296
- checked_magnitudes[variable_id] = 1.0
297
- else:
298
- checked_magnitudes[variable_id] = magnitudes[variable_id]
299
-
300
- return checked_magnitudes
301
-
302
268
  @abstractmethod
303
269
  def run(self) -> Results:
304
270
  """
@@ -406,7 +372,7 @@ class ForwardSimulation(AbstractSimulation):
406
372
  ):
407
373
  self.state.reset_state_vector()
408
374
 
409
- sol = self.solver.solve(self.state, self.eq_system, self.magnitudes)
375
+ sol = self.solver.solve(self.state, self.eq_system)
410
376
 
411
377
  if sol.converged is False:
412
378
  inter_time = 0.5 * self.time_manager.current_step_size
@@ -81,31 +81,8 @@ class AbstractSolver(ABC):
81
81
  self.tolerance = tolerance
82
82
  self.iteration_max = iteration_max
83
83
 
84
- def _get_state_magnitude(
85
- self, state: State, magnitudes: dict[str, float] | None = None
86
- ) -> NDArray[np.float64]:
87
- if magnitudes is None:
88
- return np.ones(
89
- state.size,
90
- )
91
-
92
- mag_dict = {}
93
- for var_mag_key, var_mag_value in magnitudes.items():
94
- var_index = state.get_variable_index(var_mag_key)
95
- mag_dict[var_index] = var_mag_value
96
- sorted_mag = sorted(mag_dict.items())
97
- state_mag_list = [x[1] for x in sorted_mag]
98
- return np.array(
99
- state_mag_list,
100
- )
101
-
102
84
  @abstractmethod
103
- def solve(
104
- self,
105
- state: State,
106
- system: EqSystem,
107
- magnitudes: dict[str, float] | None = None,
108
- ) -> Solution:
85
+ def solve(self, state: State, system: EqSystem) -> Solution:
109
86
  """
110
87
  Child classes have to override this method
111
88
 
@@ -114,6 +91,31 @@ class AbstractSolver(ABC):
114
91
  """
115
92
 
116
93
 
94
+ LINEAR_SOLVER = "linear_solver"
95
+
96
+
97
+ @register_type(LINEAR_SOLVER)
98
+ class LinearSolver(AbstractSolver):
99
+ """
100
+ Implementation of the :class:`~.AbstractSolver` class for linear problems.
101
+ """
102
+
103
+ def solve(self, state: State, system: EqSystem) -> Solution:
104
+ """
105
+ Solve the equation system directly
106
+
107
+ :return: the solution
108
+ :rtype: Solution
109
+ """
110
+ res = system.compute_residual()
111
+ grad = system.compute_gradient()
112
+
113
+ xn = np.linalg.solve(grad, res)
114
+ x = state.state_vector - xn
115
+
116
+ return Solution(x, True)
117
+
118
+
117
119
  # Type id for the Newton Solver
118
120
  NEWTON_SOLVER_TYPE_ID = "newton_solver"
119
121
 
@@ -166,12 +168,7 @@ class NewtonSolver(AbstractSolver):
166
168
  grad_rescaled = gradient * grad_mag_inv
167
169
  return res_rescaled, grad_rescaled
168
170
 
169
- def solve(
170
- self,
171
- state: State,
172
- system: EqSystem,
173
- magnitudes: dict[str, float] | None = None,
174
- ) -> Solution:
171
+ def solve(self, state: State, system: EqSystem) -> Solution:
175
172
  """
176
173
  Solve the equation system using the Newton method.
177
174
 
@@ -183,15 +180,16 @@ class NewtonSolver(AbstractSolver):
183
180
  try:
184
181
  i = 0
185
182
  # initialize residual and magnitude
186
- state_mag = self._get_state_magnitude(state, magnitudes)
187
183
  res = np.ones(state.state_vector.shape)
188
184
 
189
185
  # step 0 outside ou the loop to compute the residual and gradient
190
186
  # magnitude
191
187
  res, grad = self._compute_residual_and_gradient(system)
192
- res_mag_inv, grad_mag_inv = self._compute_res_grad_mag(grad, state_mag)
188
+ res_mag_inv, grad_mag_inv = self._compute_res_grad_mag(
189
+ grad, state.state_magnitudes
190
+ )
193
191
  res, grad = self._rescale_res_grad(res, res_mag_inv, grad, grad_mag_inv)
194
- x = self._compute_new_state(state, res, grad, state_mag)
192
+ x = self._compute_new_state(state, res, grad, state.state_magnitudes)
195
193
  state.update_state_vector(x)
196
194
 
197
195
  # Begin loop at iteration 1 (0 already done)
@@ -204,7 +202,9 @@ class NewtonSolver(AbstractSolver):
204
202
  res, grad = self._rescale_res_grad(
205
203
  res, res_mag_inv, grad, grad_mag_inv
206
204
  )
207
- x = self._compute_new_state(state, res, grad, state_mag)
205
+ x = self._compute_new_state(
206
+ state, res, grad, state.state_magnitudes
207
+ )
208
208
  state.update_state_vector(x)
209
209
  i += 1
210
210
 
@@ -28,7 +28,7 @@
28
28
  Define the **State** that holds simulation variables.
29
29
  """
30
30
 
31
- from collections.abc import Callable, Generator, Mapping
31
+ from collections.abc import Callable, Generator, Mapping, Sized
32
32
  from pprint import pformat
33
33
  from typing import Any
34
34
 
@@ -53,8 +53,12 @@ class State:
53
53
  _variables: dict[str, Quantity[Any]]
54
54
  """The variables ids and quantities values"""
55
55
 
56
+ _magnitudes: dict[str, Any]
57
+ """The variables magnitudes"""
58
+
56
59
  def __init__(self) -> None:
57
60
  self._variables = {}
61
+ self._magnitudes = {}
58
62
 
59
63
  @property
60
64
  def size(self) -> int:
@@ -76,6 +80,16 @@ class State:
76
80
  """
77
81
  return self._variables.copy()
78
82
 
83
+ @property
84
+ def magnitudes(self) -> dict[str, Any]:
85
+ """
86
+ Get a mapping of variables names and magnitudes.
87
+
88
+ :return: the variables names and magnitudes.
89
+ :rtype: dict[str, Quantity]
90
+ """
91
+ return self._magnitudes.copy()
92
+
79
93
  @property
80
94
  def state_vector(self) -> NDArray[np.float64]:
81
95
  """
@@ -91,8 +105,23 @@ class State:
91
105
  else:
92
106
  return np.array([])
93
107
 
94
- def __array__(self) -> NDArray[Any]:
95
- return self.state_vector
108
+ @property
109
+ def state_magnitudes(self) -> NDArray[np.float64]:
110
+ """
111
+ Get the state variables magnitudes.
112
+
113
+ :return: the state variables magnitudes
114
+ :rtype: NDArray[np.float64]
115
+ """
116
+ if len(self._variables) > 0:
117
+ return np.concatenate(
118
+ [self._magnitudes[var_id] for var_id in self._variables], axis=None
119
+ )
120
+ else:
121
+ return np.array([])
122
+
123
+ def __array__(self, *args: Any, **kwargs: Any) -> NDArray[Any]:
124
+ return np.array(self.state_vector, *args, **kwargs)
96
125
 
97
126
  def __getitem__(self, var_id: str) -> Quantity[Any]:
98
127
  """
@@ -311,7 +340,7 @@ class State:
311
340
  quantity_part = x[var_index : var_index + quantity.size]
312
341
  func(quantity, quantity_part)
313
342
 
314
- def add_variable(self, var_id: str, var_value: Any) -> None:
343
+ def add_variable(self, var_id: str, var_value: Any, magnitude: Any = None) -> None:
315
344
  """
316
345
  Add a variable to the state.
317
346
 
@@ -328,6 +357,21 @@ class State:
328
357
  quantity = var_value if isinstance(var_value, Quantity) else Quantity(var_value)
329
358
  self._variables[var_id] = quantity
330
359
 
360
+ if magnitude is not None:
361
+ if quantity.size == 1 and isinstance(magnitude, float):
362
+ self._magnitudes[var_id] = magnitude
363
+ elif isinstance(magnitude, float):
364
+ self._magnitudes[var_id] = [magnitude] * quantity.size
365
+ elif isinstance(magnitude, Sized) and len(magnitude) == quantity.size:
366
+ self._magnitudes[var_id] = magnitude
367
+ else:
368
+ raise ValueError("Variable and magnitude sizes mismatch")
369
+ else:
370
+ if quantity.size == 1:
371
+ self._magnitudes[var_id] = 1.0
372
+ else:
373
+ self._magnitudes[var_id] = [1.0] * quantity.size
374
+
331
375
  def remove_variable(self, var_id: str) -> None:
332
376
  """
333
377
  Remove a variable from the state
@@ -338,3 +382,22 @@ class State:
338
382
  # remove the variable
339
383
  if var_id in self._variables:
340
384
  self._variables.pop(var_id)
385
+
386
+ if var_id in self._magnitudes:
387
+ self._magnitudes.pop(var_id)
388
+
389
+ def set_variables_magnitudes(self, magnitudes: dict[str, Any]) -> None:
390
+ """
391
+ Update all the state variables magnitudes.
392
+
393
+ :param magnitudes: the state variables magnitudes
394
+ :type magnitudes: dict[str, Any]
395
+
396
+ :raise KeyError: Raise a KeyError if one or more of the magnitude parameters key
397
+ is not in the state.
398
+ """
399
+
400
+ if set(magnitudes.keys()).issubset(self._variables.keys()) is False:
401
+ difference = set(magnitudes.keys()).difference(self._variables.keys())
402
+ raise KeyError(str.format("State has no variables named {0}.", difference))
403
+ self._magnitudes.update(magnitudes)
@@ -77,22 +77,16 @@ def gradient_test_from_file(config_file_path: str) -> bool:
77
77
  :param config_file_path: the file path to the simulation configuration file.
78
78
  :type config_file_path: str
79
79
 
80
- :return: True if the gradient test is successfull, false otherwise.
80
+ :return: True if the gradient test is successful, false otherwise.
81
81
  """
82
82
  configuration = read_json(config_file_path)
83
83
  configuration = unwrap_aliases(configuration)
84
84
  sim: AbstractSimulation = load(configuration)
85
85
  sim._initialize() # noqa SLF001
86
- return gradient_test(
87
- sim.eq_system,
88
- sim.state,
89
- sim.solver._get_state_magnitude(sim.state, sim.magnitudes), # noqa: SLF001
90
- )
86
+ return gradient_test(sim.eq_system, sim.state)
91
87
 
92
88
 
93
- def gradient_test_from_model(
94
- model: ModelComponent, state: State, state_magnitude: NDArray[np.float64]
95
- ) -> bool:
89
+ def gradient_test_from_model(model: ModelComponent, state: State) -> bool:
96
90
  """
97
91
  Create an equation system for the given block only and perform a gradient test.
98
92
 
@@ -106,10 +100,7 @@ def gradient_test_from_model(
106
100
  :param state: the state used to determine the variables in the model.
107
101
  :type state: str
108
102
 
109
- :param state_magnitude: the state variables magnitudes
110
- :type state_magnitude: str
111
-
112
- :return: True if the gradient test is successfull, false otherwise.
103
+ :return: True if the gradient test is successful, false otherwise.
113
104
  """
114
105
  line_index = 0
115
106
  expressions = setup.SystemExpressions()
@@ -124,14 +115,11 @@ def gradient_test_from_model(
124
115
 
125
116
  eq_system = setup.build_eq_system(expressions, state)
126
117
  model.initialize()
127
- return gradient_test(eq_system, state, state_magnitude)
118
+ return gradient_test(eq_system, state)
128
119
 
129
120
 
130
121
  def gradient_test_from_expression(
131
- expr: Expression,
132
- expr_params: Any,
133
- state: State,
134
- state_magnitude: NDArray[np.float64],
122
+ expr: Expression, expr_params: Any, state: State
135
123
  ) -> bool:
136
124
  """
137
125
  Create an equation system for the given expression only and perform a gradient test.
@@ -145,20 +133,15 @@ def gradient_test_from_expression(
145
133
  :param state: the state used to determine the variables in the expression.
146
134
  :type state: str
147
135
 
148
- :param state_magnitude: the state variables magnitudes
149
- :type state_magnitude: str
150
-
151
- :return: True if the gradient test is successfull, false otherwise.
136
+ :return: True if the gradient test is successful, false otherwise.
152
137
  :rtype: bool
153
138
  """
154
139
 
155
140
  eq_system = setup.build_eq_system([(0, expr, expr_params)], state)
156
- return gradient_test(eq_system, state, state_magnitude)
141
+ return gradient_test(eq_system, state)
157
142
 
158
143
 
159
- def gradient_test(
160
- eq_system: EqSystem, state: State, state_magnitude: NDArray[np.float64]
161
- ) -> bool:
144
+ def gradient_test(eq_system: EqSystem, state: State) -> bool:
162
145
  """
163
146
  Test the computed gradient for the equation system by comparing it to
164
147
  a gradient estimated with finite differences.
@@ -170,9 +153,6 @@ def gradient_test(
170
153
  :param state: system state
171
154
  :type state: State
172
155
 
173
- :param state_magnitude: the state variables magnitudes
174
- :type state_magnitude: str
175
-
176
156
  :return: True if the estimated and computed gradient meet tolerance,
177
157
  False otherwise.
178
158
  """
@@ -180,9 +160,9 @@ def gradient_test(
180
160
  _logger.info(str.format("State:{0}{1}", linesep, state))
181
161
  _logger.info(str.format("System:{0}{1}", linesep, eq_system))
182
162
 
183
- new_state = state.state_vector + _NEW_STATE_SHIFT_FACTOR * state_magnitude
163
+ new_state = state.state_vector + _NEW_STATE_SHIFT_FACTOR * state.state_magnitudes
184
164
 
185
- shift_1 = _SHIFT_FACTOR * state_magnitude
165
+ shift_1 = _SHIFT_FACTOR * state.state_magnitudes
186
166
  state.update_state_vector(new_state)
187
167
 
188
168
  res = eq_system.compute_residual()
@@ -186,7 +186,9 @@ def simulation_reference(net_reference: Net, ref_flux_expressions, ref_nodes):
186
186
  ):
187
187
  factory = SimulationFactory(AbstractSimulation, AbstractSolver(), net_reference)
188
188
  sim = factory.create_simulation()
189
- sim.magnitudes = {str.format("{0}.{1}", NODE_A_ID, DOF_TYPE_ID): 1.1}
189
+ sim.state.set_variables_magnitudes(
190
+ {str.format("{0}.{1}", NODE_A_ID, DOF_TYPE_ID): 1.1}
191
+ )
190
192
  sim.register_timed_parameter_update(INLET_FLUX_CONDITION_ID, AbstractFunction())
191
193
  sim.register_output_function(OUTPUT_ID, AbstractFunction())
192
194
  sim.parameters[VECTOR_ID] = 3 * [0.0]
@@ -24,7 +24,6 @@
24
24
  # You should have received a copy of the GNU Lesser General Public License along with
25
25
  # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
26
 
27
- import numpy as np
28
27
  import pytest
29
28
 
30
29
  from physioblocks.computing.quantities import Quantity
@@ -48,9 +47,8 @@ class TestCBlock:
48
47
  state = State()
49
48
  state["pressure"] = ref_c_block.pressure
50
49
  ref_c_block.time.update(0.001)
51
- magnitudes = np.array([1e5])
52
50
 
53
- assert gradient_test_from_model(ref_c_block, state, magnitudes)
51
+ assert gradient_test_from_model(ref_c_block, state)
54
52
 
55
53
 
56
54
  @pytest.fixture
@@ -71,9 +69,7 @@ class TestRCBlock:
71
69
  state["pressure_2"] = ref_rc_block.pressure_2
72
70
  ref_rc_block.time.update(0.001)
73
71
 
74
- magnitudes = np.array([1e5, 1e5])
75
-
76
- assert gradient_test_from_model(ref_rc_block, state, magnitudes)
72
+ assert gradient_test_from_model(ref_rc_block, state)
77
73
 
78
74
 
79
75
  @pytest.fixture
@@ -97,6 +93,4 @@ class TestRCRBlock:
97
93
  state["pressure_2"] = ref_rcr_block.pressure_2
98
94
  ref_rcr_block.time.update(0.001)
99
95
 
100
- magnitudes = np.array([1e4, 1e4, 1e4])
101
-
102
- assert gradient_test_from_model(ref_rcr_block, state, magnitudes)
96
+ assert gradient_test_from_model(ref_rcr_block, state)