ANYfeSolver 0.5.0a1__py3-none-any.whl

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 (751) hide show
  1. anyfesolver/__init__.py +1075 -0
  2. anyfesolver/_b2_attachment_elimination_dev.py +261 -0
  3. anyfesolver/_b2_f10_f11_point_attachment.py +163 -0
  4. anyfesolver/_b2_loaded_point_trace_dev.py +173 -0
  5. anyfesolver/_b2_physical_flexibility_linear.py +707 -0
  6. anyfesolver/_b2_physical_linear_batch_dev.py +491 -0
  7. anyfesolver/_b2_physical_linear_definition.py +415 -0
  8. anyfesolver/_b2_physical_load_bubbles.py +282 -0
  9. anyfesolver/_compensated_contractions.py +497 -0
  10. anyfesolver/_compensated_native.py +437 -0
  11. anyfesolver/_corotational_batch.py +219 -0
  12. anyfesolver/_director_trace.py +214 -0
  13. anyfesolver/_dyadic_bilinear.py +76 -0
  14. anyfesolver/_dyadic_factor_chain.py +25 -0
  15. anyfesolver/_ge_beam3_adaptive_arc_program.py +286 -0
  16. anyfesolver/_ge_beam3_analysis_combined.py +102 -0
  17. anyfesolver/_ge_beam3_analysis_fibre_translation.py +130 -0
  18. anyfesolver/_ge_beam3_analysis_modal_snapshot.py +27 -0
  19. anyfesolver/_ge_beam3_analysis_nodal_program.py +140 -0
  20. anyfesolver/_ge_beam3_analysis_translation.py +147 -0
  21. anyfesolver/_ge_beam3_analysis_translation_modal.py +84 -0
  22. anyfesolver/_ge_beam3_arc_geometry.py +89 -0
  23. anyfesolver/_ge_beam3_arc_program.py +304 -0
  24. anyfesolver/_ge_beam3_authoritative_cell_seed.py +25 -0
  25. anyfesolver/_ge_beam3_cell_identity.py +52 -0
  26. anyfesolver/_ge_beam3_centered_batched_finite_inertia.py +132 -0
  27. anyfesolver/_ge_beam3_centered_finite_inertia.py +171 -0
  28. anyfesolver/_ge_beam3_centered_mixed.py +104 -0
  29. anyfesolver/_ge_beam3_centered_reference.py +187 -0
  30. anyfesolver/_ge_beam3_centered_so3_strain.py +76 -0
  31. anyfesolver/_ge_beam3_complementary_section.py +122 -0
  32. anyfesolver/_ge_beam3_compliance_snapshot_guard.py +20 -0
  33. anyfesolver/_ge_beam3_connected_dynamic.py +486 -0
  34. anyfesolver/_ge_beam3_connected_trajectory.py +258 -0
  35. anyfesolver/_ge_beam3_conservative_backtrack.py +26 -0
  36. anyfesolver/_ge_beam3_controlled_fibre_modes.py +105 -0
  37. anyfesolver/_ge_beam3_coupled_beam_subdomain.py +128 -0
  38. anyfesolver/_ge_beam3_coupled_modes.py +256 -0
  39. anyfesolver/_ge_beam3_deterministic_reduction.py +264 -0
  40. anyfesolver/_ge_beam3_displacement_program.py +255 -0
  41. anyfesolver/_ge_beam3_durable_coupled.py +251 -0
  42. anyfesolver/_ge_beam3_dynamic_elastic_state.py +461 -0
  43. anyfesolver/_ge_beam3_effective_deadline.py +58 -0
  44. anyfesolver/_ge_beam3_elastic_seed_continuation.py +223 -0
  45. anyfesolver/_ge_beam3_elastic_seed_modal.py +139 -0
  46. anyfesolver/_ge_beam3_equilibrium_line_program.py +98 -0
  47. anyfesolver/_ge_beam3_equilibrium_schur_solver.py +96 -0
  48. anyfesolver/_ge_beam3_factor_chain_modes.py +103 -0
  49. anyfesolver/_ge_beam3_fibre_cell.py +408 -0
  50. anyfesolver/_ge_beam3_fibre_distributed_couples.py +191 -0
  51. anyfesolver/_ge_beam3_fibre_kinematic_cell.py +75 -0
  52. anyfesolver/_ge_beam3_fibre_line_program.py +157 -0
  53. anyfesolver/_ge_beam3_fibre_line_work.py +87 -0
  54. anyfesolver/_ge_beam3_fibre_reference_modal.py +104 -0
  55. anyfesolver/_ge_beam3_fibre_schur_solver.py +134 -0
  56. anyfesolver/_ge_beam3_fibre_section.py +286 -0
  57. anyfesolver/_ge_beam3_fibre_static_boundary.py +113 -0
  58. anyfesolver/_ge_beam3_g1_analysis.py +307 -0
  59. anyfesolver/_ge_beam3_g1_elastic.py +161 -0
  60. anyfesolver/_ge_beam3_g1_element.py +185 -0
  61. anyfesolver/_ge_beam3_g1_operator.py +137 -0
  62. anyfesolver/_ge_beam3_g2_analysis.py +176 -0
  63. anyfesolver/_ge_beam3_g2_constraints.py +162 -0
  64. anyfesolver/_ge_beam3_g3_analysis.py +385 -0
  65. anyfesolver/_ge_beam3_g3_constraints.py +168 -0
  66. anyfesolver/_ge_beam3_g3b_owner.py +296 -0
  67. anyfesolver/_ge_beam3_g3b_q4_reference.py +186 -0
  68. anyfesolver/_ge_beam3_g3b_reference.py +206 -0
  69. anyfesolver/_ge_beam3_g3b_result_schema.py +107 -0
  70. anyfesolver/_ge_beam3_g3b_s3_reference.py +185 -0
  71. anyfesolver/_ge_beam3_g3b_weighted_reference.py +193 -0
  72. anyfesolver/_ge_beam3_g3c_affine_q4_chart.py +58 -0
  73. anyfesolver/_ge_beam3_g3c_affine_q4_increment_chart.py +257 -0
  74. anyfesolver/_ge_beam3_g3c_affine_q4_recovery.py +434 -0
  75. anyfesolver/_ge_beam3_g3c_affine_q4_registry.py +127 -0
  76. anyfesolver/_ge_beam3_g3c_b2_physical.py +153 -0
  77. anyfesolver/_ge_beam3_g3c_b2_physical_adapter.py +160 -0
  78. anyfesolver/_ge_beam3_g3c_definition.py +117 -0
  79. anyfesolver/_ge_beam3_g3c_local_beam.py +188 -0
  80. anyfesolver/_ge_beam3_g3c_local_shell.py +371 -0
  81. anyfesolver/_ge_beam3_g3c_owner.py +400 -0
  82. anyfesolver/_ge_beam3_g3c_physical_authority.py +203 -0
  83. anyfesolver/_ge_beam3_g3c_physical_owner.py +556 -0
  84. anyfesolver/_ge_beam3_g3c_recovery.py +91 -0
  85. anyfesolver/_ge_beam3_g3c_so3_numerics.py +81 -0
  86. anyfesolver/_ge_beam3_g3c_stable/__init__.py +1 -0
  87. anyfesolver/_ge_beam3_g3c_stable/authority.py +152 -0
  88. anyfesolver/_ge_beam3_g3c_stable/beam.py +196 -0
  89. anyfesolver/_ge_beam3_g3c_stable/boundary.py +38 -0
  90. anyfesolver/_ge_beam3_g3c_stable/chart.py +23 -0
  91. anyfesolver/_ge_beam3_g3c_stable/compensated.py +46 -0
  92. anyfesolver/_ge_beam3_g3c_stable/element.py +190 -0
  93. anyfesolver/_ge_beam3_g3c_stable/fit.py +54 -0
  94. anyfesolver/_ge_beam3_g3c_stable/joint.py +255 -0
  95. anyfesolver/_ge_beam3_g3c_stable/line_work.py +92 -0
  96. anyfesolver/_ge_beam3_g3c_stable/operator.py +147 -0
  97. anyfesolver/_ge_beam3_g3c_stable/owner.py +415 -0
  98. anyfesolver/_ge_beam3_g3c_stable/shell.py +358 -0
  99. anyfesolver/_ge_beam3_g4_completion.py +186 -0
  100. anyfesolver/_ge_beam3_g4a_station_transaction.py +385 -0
  101. anyfesolver/_ge_beam3_g5_completion.py +68 -0
  102. anyfesolver/_ge_beam3_g6_domain.py +354 -0
  103. anyfesolver/_ge_beam3_generalized_cell.py +172 -0
  104. anyfesolver/_ge_beam3_generalized_ellipsoid_section.py +215 -0
  105. anyfesolver/_ge_beam3_generalized_static_boundary.py +233 -0
  106. anyfesolver/_ge_beam3_lifted_kinetic_factor.py +26 -0
  107. anyfesolver/_ge_beam3_line_fibre_modes.py +121 -0
  108. anyfesolver/_ge_beam3_load_program.py +275 -0
  109. anyfesolver/_ge_beam3_loaded_modal.py +225 -0
  110. anyfesolver/_ge_beam3_mixed_ad.py +286 -0
  111. anyfesolver/_ge_beam3_native_analysis.py +484 -0
  112. anyfesolver/_ge_beam3_native_arc.py +269 -0
  113. anyfesolver/_ge_beam3_native_arc_adaptive.py +251 -0
  114. anyfesolver/_ge_beam3_native_arc_restart.py +88 -0
  115. anyfesolver/_ge_beam3_native_arc_source.py +62 -0
  116. anyfesolver/_ge_beam3_native_buckling.py +206 -0
  117. anyfesolver/_ge_beam3_native_combined_couples.py +179 -0
  118. anyfesolver/_ge_beam3_native_combined_restart.py +205 -0
  119. anyfesolver/_ge_beam3_native_definition.py +238 -0
  120. anyfesolver/_ge_beam3_native_distributed_element.py +220 -0
  121. anyfesolver/_ge_beam3_native_distributed_loading.py +92 -0
  122. anyfesolver/_ge_beam3_native_distributed_program.py +165 -0
  123. anyfesolver/_ge_beam3_native_distributed_recovery.py +34 -0
  124. anyfesolver/_ge_beam3_native_distributed_restart.py +221 -0
  125. anyfesolver/_ge_beam3_native_dynamic_analysis.py +149 -0
  126. anyfesolver/_ge_beam3_native_dynamic_restart.py +261 -0
  127. anyfesolver/_ge_beam3_native_fibre_current_modal.py +104 -0
  128. anyfesolver/_ge_beam3_native_fibre_recovery.py +34 -0
  129. anyfesolver/_ge_beam3_native_fibre_restart.py +211 -0
  130. anyfesolver/_ge_beam3_native_fibre_static_element.py +193 -0
  131. anyfesolver/_ge_beam3_native_force_adaptation.py +56 -0
  132. anyfesolver/_ge_beam3_native_generalized_combined_couples.py +188 -0
  133. anyfesolver/_ge_beam3_native_generalized_combined_restart.py +207 -0
  134. anyfesolver/_ge_beam3_native_generalized_element.py +222 -0
  135. anyfesolver/_ge_beam3_native_generalized_factor_modal.py +122 -0
  136. anyfesolver/_ge_beam3_native_generalized_loading.py +92 -0
  137. anyfesolver/_ge_beam3_native_generalized_modal.py +274 -0
  138. anyfesolver/_ge_beam3_native_generalized_paired_modal.py +13 -0
  139. anyfesolver/_ge_beam3_native_generalized_parameter.py +89 -0
  140. anyfesolver/_ge_beam3_native_generalized_program.py +196 -0
  141. anyfesolver/_ge_beam3_native_generalized_recovery.py +34 -0
  142. anyfesolver/_ge_beam3_native_generalized_restart.py +243 -0
  143. anyfesolver/_ge_beam3_native_history_profile.py +53 -0
  144. anyfesolver/_ge_beam3_native_line_loading.py +93 -0
  145. anyfesolver/_ge_beam3_native_line_program.py +150 -0
  146. anyfesolver/_ge_beam3_native_line_recovery.py +34 -0
  147. anyfesolver/_ge_beam3_native_line_restart.py +197 -0
  148. anyfesolver/_ge_beam3_native_line_static_element.py +220 -0
  149. anyfesolver/_ge_beam3_native_load_admission.py +37 -0
  150. anyfesolver/_ge_beam3_native_midpoint.py +1004 -0
  151. anyfesolver/_ge_beam3_native_multi_shell_contact.py +539 -0
  152. anyfesolver/_ge_beam3_native_pair_contact.py +236 -0
  153. anyfesolver/_ge_beam3_native_shell_contact.py +357 -0
  154. anyfesolver/_ge_beam3_native_spatial_couples.py +176 -0
  155. anyfesolver/_ge_beam3_native_spatial_restart.py +204 -0
  156. anyfesolver/_ge_beam3_native_transient.py +467 -0
  157. anyfesolver/_ge_beam3_native_translation.py +225 -0
  158. anyfesolver/_ge_beam3_native_translation_restart.py +54 -0
  159. anyfesolver/_ge_beam3_operator_validation_scope.py +53 -0
  160. anyfesolver/_ge_beam3_p5/__init__.py +11 -0
  161. anyfesolver/_ge_beam3_p5/algebra.py +91 -0
  162. anyfesolver/_ge_beam3_p5/arrays.py +29 -0
  163. anyfesolver/_ge_beam3_p5/chart.py +45 -0
  164. anyfesolver/_ge_beam3_p5/codec.py +82 -0
  165. anyfesolver/_ge_beam3_p5/committed_modal.py +191 -0
  166. anyfesolver/_ge_beam3_p5/compensated.py +118 -0
  167. anyfesolver/_ge_beam3_p5/compensated_coordinates.py +44 -0
  168. anyfesolver/_ge_beam3_p5/core.py +159 -0
  169. anyfesolver/_ge_beam3_p5/element.py +207 -0
  170. anyfesolver/_ge_beam3_p5/factors.py +61 -0
  171. anyfesolver/_ge_beam3_p5/inertia.py +120 -0
  172. anyfesolver/_ge_beam3_p5/mass.py +70 -0
  173. anyfesolver/_ge_beam3_p5/mixed.py +256 -0
  174. anyfesolver/_ge_beam3_p5/reference_modal.py +73 -0
  175. anyfesolver/_ge_beam3_p5/section.py +139 -0
  176. anyfesolver/_ge_beam3_p5/typed_schema.py +111 -0
  177. anyfesolver/_ge_beam3_p5_centered/__init__.py +6 -0
  178. anyfesolver/_ge_beam3_p5_centered/codec.py +84 -0
  179. anyfesolver/_ge_beam3_p5_centered/committed_modal.py +192 -0
  180. anyfesolver/_ge_beam3_p5_centered/core.py +171 -0
  181. anyfesolver/_ge_beam3_p5_centered/element.py +216 -0
  182. anyfesolver/_ge_beam3_p5_centered/mass.py +99 -0
  183. anyfesolver/_ge_beam3_p5_centered/positions.py +34 -0
  184. anyfesolver/_ge_beam3_p5_centered/reference_modal.py +73 -0
  185. anyfesolver/_ge_beam3_p5_coordinates/__init__.py +6 -0
  186. anyfesolver/_ge_beam3_p5_coordinates/codec.py +84 -0
  187. anyfesolver/_ge_beam3_p5_coordinates/committed_modal.py +192 -0
  188. anyfesolver/_ge_beam3_p5_coordinates/core.py +163 -0
  189. anyfesolver/_ge_beam3_p5_coordinates/element.py +213 -0
  190. anyfesolver/_ge_beam3_p5_coordinates/positions.py +102 -0
  191. anyfesolver/_ge_beam3_p5_coordinates/reference_modal.py +73 -0
  192. anyfesolver/_ge_beam3_p5_loads/__init__.py +7 -0
  193. anyfesolver/_ge_beam3_p5_loads/codec.py +85 -0
  194. anyfesolver/_ge_beam3_p5_loads/core.py +192 -0
  195. anyfesolver/_ge_beam3_p5_loads/element.py +243 -0
  196. anyfesolver/_ge_beam3_p5_loads/state.py +120 -0
  197. anyfesolver/_ge_beam3_p5_loads/work.py +45 -0
  198. anyfesolver/_ge_beam3_p5_seeded/__init__.py +9 -0
  199. anyfesolver/_ge_beam3_p5_seeded/codec.py +87 -0
  200. anyfesolver/_ge_beam3_p5_seeded/core.py +197 -0
  201. anyfesolver/_ge_beam3_p5_seeded/element.py +245 -0
  202. anyfesolver/_ge_beam3_p5_seeded/state.py +122 -0
  203. anyfesolver/_ge_beam3_p5_seeded/work.py +47 -0
  204. anyfesolver/_ge_beam3_pose_joint.py +268 -0
  205. anyfesolver/_ge_beam3_precise_geometric_work.py +147 -0
  206. anyfesolver/_ge_beam3_reassembled_signed_modes.py +101 -0
  207. anyfesolver/_ge_beam3_reference_identity.py +92 -0
  208. anyfesolver/_ge_beam3_refined_fibre_schur_solver.py +104 -0
  209. anyfesolver/_ge_beam3_refinement_capacity.py +19 -0
  210. anyfesolver/_ge_beam3_relative_virgin_reference_modes.py +60 -0
  211. anyfesolver/_ge_beam3_retained_arc.py +350 -0
  212. anyfesolver/_ge_beam3_retained_arc_geometry.py +66 -0
  213. anyfesolver/_ge_beam3_retained_arc_modal.py +125 -0
  214. anyfesolver/_ge_beam3_retained_elastic.py +134 -0
  215. anyfesolver/_ge_beam3_retained_fibre.py +209 -0
  216. anyfesolver/_ge_beam3_retained_fibre_control.py +270 -0
  217. anyfesolver/_ge_beam3_retained_fibre_element.py +58 -0
  218. anyfesolver/_ge_beam3_retained_fibre_modal.py +155 -0
  219. anyfesolver/_ge_beam3_retained_fibre_modes.py +189 -0
  220. anyfesolver/_ge_beam3_retained_fibre_program.py +68 -0
  221. anyfesolver/_ge_beam3_retained_fibre_state.py +268 -0
  222. anyfesolver/_ge_beam3_retained_force_program.py +72 -0
  223. anyfesolver/_ge_beam3_retained_generalized.py +186 -0
  224. anyfesolver/_ge_beam3_retained_generalized_modal.py +171 -0
  225. anyfesolver/_ge_beam3_retained_generalized_program.py +63 -0
  226. anyfesolver/_ge_beam3_retained_generalized_state.py +281 -0
  227. anyfesolver/_ge_beam3_retained_nodal_loading.py +111 -0
  228. anyfesolver/_ge_beam3_retained_plastic.py +116 -0
  229. anyfesolver/_ge_beam3_retained_plastic_modes.py +144 -0
  230. anyfesolver/_ge_beam3_retained_plastic_program.py +69 -0
  231. anyfesolver/_ge_beam3_retained_plastic_state.py +165 -0
  232. anyfesolver/_ge_beam3_retained_state.py +194 -0
  233. anyfesolver/_ge_beam3_retained_translation_control.py +345 -0
  234. anyfesolver/_ge_beam3_retained_translation_modal.py +137 -0
  235. anyfesolver/_ge_beam3_schur_line_program.py +98 -0
  236. anyfesolver/_ge_beam3_seeded_fibre_control.py +175 -0
  237. anyfesolver/_ge_beam3_seeded_load_program.py +301 -0
  238. anyfesolver/_ge_beam3_seeded_loaded_modal.py +226 -0
  239. anyfesolver/_ge_beam3_seeded_signed_modes.py +150 -0
  240. anyfesolver/_ge_beam3_shared_kinematic_split.py +53 -0
  241. anyfesolver/_ge_beam3_shell_joint_state.py +396 -0
  242. anyfesolver/_ge_beam3_shell_joint_trial.py +217 -0
  243. anyfesolver/_ge_beam3_signed_loaded_modes.py +140 -0
  244. anyfesolver/_ge_beam3_spatial_fibre_program.py +113 -0
  245. anyfesolver/_ge_beam3_spatial_nodal_moments.py +38 -0
  246. anyfesolver/_ge_beam3_station_resultant_cell.py +235 -0
  247. anyfesolver/_ge_beam3_variational_shell.py +211 -0
  248. anyfesolver/_ge_beam3_virgin_reference_modes.py +60 -0
  249. anyfesolver/_impact_coupling.py +162 -0
  250. anyfesolver/_native_authority_dag.py +77 -0
  251. anyfesolver/_native_dyadic_interval_inertia.py +64 -0
  252. anyfesolver/_native_exact_shift_chain_modes.py +140 -0
  253. anyfesolver/_native_exact_shift_inertia.py +86 -0
  254. anyfesolver/_native_factor_chain_modes.py +192 -0
  255. anyfesolver/_native_guard.cpp +828 -0
  256. anyfesolver/_native_guard_dispatch.py +140 -0
  257. anyfesolver/_native_large_factor_chain.py +55 -0
  258. anyfesolver/_native_material_protocol.py +51 -0
  259. anyfesolver/_native_midpoint_controller.py +90 -0
  260. anyfesolver/_native_modal_capacity.py +26 -0
  261. anyfesolver/_native_paired_factor_chain_modes.py +244 -0
  262. anyfesolver/_native_reassembled_factor_modes.py +185 -0
  263. anyfesolver/_native_reference_factor_spectrum.py +102 -0
  264. anyfesolver/_native_reference_modal.py +180 -0
  265. anyfesolver/_native_relative_factor_chain_modes.py +204 -0
  266. anyfesolver/_native_relative_reference_factor_spectrum.py +110 -0
  267. anyfesolver/_native_retained_step.py +15 -0
  268. anyfesolver/_native_rotation_state.py +797 -0
  269. anyfesolver/_native_signed_factor_modes.py +257 -0
  270. anyfesolver/_native_signed_kinetic_factor_modes.py +279 -0
  271. anyfesolver/_native_stationary_spectrum.py +79 -0
  272. anyfesolver/_nonlinear_events.py +150 -0
  273. anyfesolver/_nonlinear_seed.py +80 -0
  274. anyfesolver/_paired_modal_arithmetic.py +71 -0
  275. anyfesolver/_plate_stability_continuation.py +171 -0
  276. anyfesolver/_q4_assumed_strain_plasticity.py +502 -0
  277. anyfesolver/_qualified_authority_epoch.py +561 -0
  278. anyfesolver/_relative_reference_svd.py +44 -0
  279. anyfesolver/_stiffened_shell_affine_endpoint.py +232 -0
  280. anyfesolver/_stiffened_shell_algorithmic_pullback.py +38 -0
  281. anyfesolver/_stiffened_shell_arc_checkpoint.py +422 -0
  282. anyfesolver/_stiffened_shell_arc_control.py +108 -0
  283. anyfesolver/_stiffened_shell_arc_metric.py +222 -0
  284. anyfesolver/_stiffened_shell_arc_publication.py +153 -0
  285. anyfesolver/_stiffened_shell_arc_trial.py +310 -0
  286. anyfesolver/_stiffened_shell_b2_affine_resolution.py +101 -0
  287. anyfesolver/_stiffened_shell_b2_assembly_diagnostics.py +172 -0
  288. anyfesolver/_stiffened_shell_b2_definition_ownership.py +189 -0
  289. anyfesolver/_stiffened_shell_b2_experimental.py +153 -0
  290. anyfesolver/_stiffened_shell_b2_nodal_footprint.py +273 -0
  291. anyfesolver/_stiffened_shell_b2_physical_rigid_footprint.py +237 -0
  292. anyfesolver/_stiffened_shell_b2_q4_panel_experimental.py +2447 -0
  293. anyfesolver/_stiffened_shell_b2_q4_point_experimental.py +251 -0
  294. anyfesolver/_stiffened_shell_b2_reference_buckling.py +413 -0
  295. anyfesolver/_stiffened_shell_b3_chart.py +70 -0
  296. anyfesolver/_stiffened_shell_b3_local_adapter.py +141 -0
  297. anyfesolver/_stiffened_shell_beam_history.py +107 -0
  298. anyfesolver/_stiffened_shell_bl5_local_experimental.py +173 -0
  299. anyfesolver/_stiffened_shell_bl5_native_elastic.py +28 -0
  300. anyfesolver/_stiffened_shell_branch_event_trial.py +58 -0
  301. anyfesolver/_stiffened_shell_consumer_capabilities.py +124 -0
  302. anyfesolver/_stiffened_shell_coordinate_support.py +110 -0
  303. anyfesolver/_stiffened_shell_displacement_adaptive.py +327 -0
  304. anyfesolver/_stiffened_shell_displacement_checkpoint.py +360 -0
  305. anyfesolver/_stiffened_shell_displacement_control.py +326 -0
  306. anyfesolver/_stiffened_shell_displacement_corrector.py +293 -0
  307. anyfesolver/_stiffened_shell_displacement_increment.py +121 -0
  308. anyfesolver/_stiffened_shell_distributing_footprint.py +354 -0
  309. anyfesolver/_stiffened_shell_distributing_pose.py +267 -0
  310. anyfesolver/_stiffened_shell_f06_increment_arithmetic.py +205 -0
  311. anyfesolver/_stiffened_shell_ge_body_load.py +300 -0
  312. anyfesolver/_stiffened_shell_ge_checkpoint_binary.py +472 -0
  313. anyfesolver/_stiffened_shell_ge_distributed_load.py +210 -0
  314. anyfesolver/_stiffened_shell_ge_distributed_programme.py +175 -0
  315. anyfesolver/_stiffened_shell_ge_distributing_finite.py +242 -0
  316. anyfesolver/_stiffened_shell_ge_distributing_reference.py +296 -0
  317. anyfesolver/_stiffened_shell_ge_experimental.py +2454 -0
  318. anyfesolver/_stiffened_shell_ge_finite_experimental.py +2714 -0
  319. anyfesolver/_stiffened_shell_ge_mixed_modal_mass.py +33 -0
  320. anyfesolver/_stiffened_shell_ge_point_buckling.py +723 -0
  321. anyfesolver/_stiffened_shell_ge_pressure_load.py +366 -0
  322. anyfesolver/_stiffened_shell_ge_reference_modal.py +580 -0
  323. anyfesolver/_stiffened_shell_generalized_recovery.py +150 -0
  324. anyfesolver/_stiffened_shell_increment_control.py +217 -0
  325. anyfesolver/_stiffened_shell_l1_assembly_experimental.py +420 -0
  326. anyfesolver/_stiffened_shell_l1_local_experimental.py +284 -0
  327. anyfesolver/_stiffened_shell_l1_supported_work_experimental.py +146 -0
  328. anyfesolver/_stiffened_shell_native_distributed_load.py +120 -0
  329. anyfesolver/_stiffened_shell_native_gravity.py +236 -0
  330. anyfesolver/_stiffened_shell_nodal_footprint.py +255 -0
  331. anyfesolver/_stiffened_shell_physical_q4_mass.py +98 -0
  332. anyfesolver/_stiffened_shell_physical_s3_mass.py +53 -0
  333. anyfesolver/_stiffened_shell_point_recovery.py +49 -0
  334. anyfesolver/_stiffened_shell_q4_algorithmic_pullback.py +88 -0
  335. anyfesolver/_stiffened_shell_q4_material_event.py +114 -0
  336. anyfesolver/_stiffened_shell_q4_reference.py +65 -0
  337. anyfesolver/_stiffened_shell_rotation_charts.py +58 -0
  338. anyfesolver/_stiffened_shell_s3_algorithmic_pullback.py +59 -0
  339. anyfesolver/_stiffened_shell_s3_conservative_buckling.py +28 -0
  340. anyfesolver/_stiffened_shell_s3_dead_work_candidate.py +107 -0
  341. anyfesolver/_stiffened_shell_s3_material_event.py +30 -0
  342. anyfesolver/_stiffened_shell_same_parent_trial.py +224 -0
  343. anyfesolver/_stiffened_shell_selected_recovery.py +113 -0
  344. anyfesolver/_stiffened_shell_staged_load_experimental.py +392 -0
  345. anyfesolver/_stiffened_shell_stress_free_reference.py +204 -0
  346. anyfesolver/_wire_types.py +17 -0
  347. anyfesolver/activity.py +1537 -0
  348. anyfesolver/algebraic_dynamics.py +2864 -0
  349. anyfesolver/analysis_session.py +897 -0
  350. anyfesolver/anystructure_fem_mode.py +1637 -0
  351. anyfesolver/arc_length.py +2587 -0
  352. anyfesolver/assembly.py +1830 -0
  353. anyfesolver/b3_ge.py +179 -0
  354. anyfesolver/baselines.py +303 -0
  355. anyfesolver/beam_sections.py +292 -0
  356. anyfesolver/beam_shell_verification.py +4685 -0
  357. anyfesolver/beam_validity.py +110 -0
  358. anyfesolver/benchmarks.py +495 -0
  359. anyfesolver/boundary.py +1680 -0
  360. anyfesolver/buckling.py +2136 -0
  361. anyfesolver/buckling_validity.py +91 -0
  362. anyfesolver/capacity_workflow.py +431 -0
  363. anyfesolver/capsule_runtime_guard.py +99 -0
  364. anyfesolver/cases.py +173 -0
  365. anyfesolver/composite_strip_verification.py +297 -0
  366. anyfesolver/concentrated_mass.py +84 -0
  367. anyfesolver/constraint_audit.py +553 -0
  368. anyfesolver/contact.py +4785 -0
  369. anyfesolver/contact_performance.py +301 -0
  370. anyfesolver/control.py +206 -0
  371. anyfesolver/corotational.py +1935 -0
  372. anyfesolver/corotational_performance.py +157 -0
  373. anyfesolver/current_state_tangent.py +2780 -0
  374. anyfesolver/cylinder_benchmarks.py +369 -0
  375. anyfesolver/damage_matrix_performance.py +617 -0
  376. anyfesolver/dynamics.py +2833 -0
  377. anyfesolver/e4_pl_element.py +8265 -0
  378. anyfesolver/e4_pl_enriched.py +194 -0
  379. anyfesolver/e4_pl_enriched_nonlinear.py +159 -0
  380. anyfesolver/e4_pl_s3_element.py +9752 -0
  381. anyfesolver/e4_pl_s3_initial_fields.py +101 -0
  382. anyfesolver/e4_pl_s3_state.py +4723 -0
  383. anyfesolver/e4_pl_s3_v2_element.py +1844 -0
  384. anyfesolver/e4_pl_s3_v2b_element.py +1936 -0
  385. anyfesolver/e4_pl_s3_v2c_element.py +2196 -0
  386. anyfesolver/e4_pl_s3_v2d_element.py +2621 -0
  387. anyfesolver/e4_pl_s3_v2d_state.py +376 -0
  388. anyfesolver/element_capabilities.py +159 -0
  389. anyfesolver/element_qualification.py +432 -0
  390. anyfesolver/elements.py +6327 -0
  391. anyfesolver/experimental_csr_assembly.py +238 -0
  392. anyfesolver/external_references.py +1253 -0
  393. anyfesolver/fe_core.py +832 -0
  394. anyfesolver/floating_pressure_regions.py +119 -0
  395. anyfesolver/floating_response.py +486 -0
  396. anyfesolver/floating_transient.py +1281 -0
  397. anyfesolver/fracture.py +621 -0
  398. anyfesolver/ge_beam3_curved_reference.py +725 -0
  399. anyfesolver/ge_beam3_element.py +885 -0
  400. anyfesolver/ge_beam3_mixed_element.py +1216 -0
  401. anyfesolver/ge_beam3_mixed_state.py +814 -0
  402. anyfesolver/ge_beam3_native.py +129 -0
  403. anyfesolver/ge_beam3_native_connected_dynamics.py +24 -0
  404. anyfesolver/ge_beam3_native_dynamics.py +70 -0
  405. anyfesolver/ge_beam3_state.py +672 -0
  406. anyfesolver/general_contact/__init__.py +151 -0
  407. anyfesolver/general_contact/_enriched_multitarget_empty.py +202 -0
  408. anyfesolver/general_contact/_enriched_multitarget_trial.py +183 -0
  409. anyfesolver/general_contact/_results_archive_common.py +65 -0
  410. anyfesolver/general_contact/algebraic_path.py +206 -0
  411. anyfesolver/general_contact/arc_contact.py +237 -0
  412. anyfesolver/general_contact/arc_results_archive.py +158 -0
  413. anyfesolver/general_contact/augmentation.py +157 -0
  414. anyfesolver/general_contact/automatic_domain.py +621 -0
  415. anyfesolver/general_contact/beam_chain_consistent.py +357 -0
  416. anyfesolver/general_contact/beam_chain_end_geometry.py +237 -0
  417. anyfesolver/general_contact/beam_chain_ends.py +220 -0
  418. anyfesolver/general_contact/beam_chain_pair.py +416 -0
  419. anyfesolver/general_contact/beam_curve_end_geometry.py +254 -0
  420. anyfesolver/general_contact/beam_curve_ends.py +237 -0
  421. anyfesolver/general_contact/beam_curve_pair.py +794 -0
  422. anyfesolver/general_contact/beam_curve_pair_static.py +303 -0
  423. anyfesolver/general_contact/beam_end_radial_geometry.py +221 -0
  424. anyfesolver/general_contact/beam_end_topology.py +15 -0
  425. anyfesolver/general_contact/beam_hemisphere_coupled_tool.py +61 -0
  426. anyfesolver/general_contact/beam_hemisphere_cylinder.py +134 -0
  427. anyfesolver/general_contact/beam_hemisphere_cylinder_motion.py +89 -0
  428. anyfesolver/general_contact/beam_hemisphere_cylinder_work.py +216 -0
  429. anyfesolver/general_contact/beam_hemisphere_plane.py +175 -0
  430. anyfesolver/general_contact/beam_hemisphere_s3_support.py +152 -0
  431. anyfesolver/general_contact/beam_hemisphere_sphere.py +135 -0
  432. anyfesolver/general_contact/beam_hemisphere_sphere_work.py +114 -0
  433. anyfesolver/general_contact/beam_hemisphere_support.py +211 -0
  434. anyfesolver/general_contact/beam_pair.py +523 -0
  435. anyfesolver/general_contact/beam_pair_end_geometry.py +269 -0
  436. anyfesolver/general_contact/beam_pair_ends.py +222 -0
  437. anyfesolver/general_contact/beam_plane.py +425 -0
  438. anyfesolver/general_contact/beam_radial.py +500 -0
  439. anyfesolver/general_contact/beam_radial_ends.py +223 -0
  440. anyfesolver/general_contact/beam_s3_directional_rates.py +196 -0
  441. anyfesolver/general_contact/beam_s3_rotational_transient.py +126 -0
  442. anyfesolver/general_contact/beam_s3_transient.py +139 -0
  443. anyfesolver/general_contact/beam_shell.py +648 -0
  444. anyfesolver/general_contact/beam_shell_patch.py +395 -0
  445. anyfesolver/general_contact/beam_temporal_bounds.py +230 -0
  446. anyfesolver/general_contact/capability.py +101 -0
  447. anyfesolver/general_contact/capped_cylinder.py +618 -0
  448. anyfesolver/general_contact/contact_search.py +95 -0
  449. anyfesolver/general_contact/core.py +1769 -0
  450. anyfesolver/general_contact/curved_s3_q4_work.py +238 -0
  451. anyfesolver/general_contact/curved_shell_skin.py +520 -0
  452. anyfesolver/general_contact/d1_interior_profile.py +427 -0
  453. anyfesolver/general_contact/deformable_beam_s3_caps.py +143 -0
  454. anyfesolver/general_contact/deformable_beam_s3_line.py +211 -0
  455. anyfesolver/general_contact/deformable_beam_s3_static.py +152 -0
  456. anyfesolver/general_contact/descriptor_rates.py +61 -0
  457. anyfesolver/general_contact/enriched_cold_predictor.py +161 -0
  458. anyfesolver/general_contact/enriched_moment_batch.py +337 -0
  459. anyfesolver/general_contact/enriched_multitarget.py +308 -0
  460. anyfesolver/general_contact/enriched_multitarget_gap.py +156 -0
  461. anyfesolver/general_contact/enriched_multitarget_moments.py +194 -0
  462. anyfesolver/general_contact/enriched_multitarget_topology.py +171 -0
  463. anyfesolver/general_contact/enriched_nonlinear.py +440 -0
  464. anyfesolver/general_contact/enriched_overlap.py +299 -0
  465. anyfesolver/general_contact/enriched_path.py +253 -0
  466. anyfesolver/general_contact/enriched_small_cut.py +310 -0
  467. anyfesolver/general_contact/enriched_static.py +481 -0
  468. anyfesolver/general_contact/enriched_union.py +320 -0
  469. anyfesolver/general_contact/equilibrated_pressure_pivot.py +140 -0
  470. anyfesolver/general_contact/event_subdivision.py +273 -0
  471. anyfesolver/general_contact/finite_mixed_state.py +133 -0
  472. anyfesolver/general_contact/finite_rigid_patch.py +196 -0
  473. anyfesolver/general_contact/finite_rigid_support.py +129 -0
  474. anyfesolver/general_contact/finite_rigid_sweep.py +53 -0
  475. anyfesolver/general_contact/finite_rotation_predictor.py +171 -0
  476. anyfesolver/general_contact/finite_rotation_skin.py +212 -0
  477. anyfesolver/general_contact/finite_rotation_state.py +106 -0
  478. anyfesolver/general_contact/finite_rotation_sweep.py +161 -0
  479. anyfesolver/general_contact/finite_v2d_state.py +104 -0
  480. anyfesolver/general_contact/fixed_projection_graph.py +205 -0
  481. anyfesolver/general_contact/fixed_projection_s3_events.py +235 -0
  482. anyfesolver/general_contact/free_rigid.py +134 -0
  483. anyfesolver/general_contact/friction_point.py +378 -0
  484. anyfesolver/general_contact/gap_extrema.py +119 -0
  485. anyfesolver/general_contact/guided_pair_transient_geometry.py +138 -0
  486. anyfesolver/general_contact/initial_contact_seed.py +368 -0
  487. anyfesolver/general_contact/linearized_pivot.py +595 -0
  488. anyfesolver/general_contact/material_work_diagnostics.py +159 -0
  489. anyfesolver/general_contact/moment_batch_ad.py +129 -0
  490. anyfesolver/general_contact/moment_batch_points.py +75 -0
  491. anyfesolver/general_contact/moving.py +1031 -0
  492. anyfesolver/general_contact/multiple_beam_rigid.py +248 -0
  493. anyfesolver/general_contact/multiple_beam_s3_caps.py +199 -0
  494. anyfesolver/general_contact/multiple_beam_s3_transient.py +223 -0
  495. anyfesolver/general_contact/multiple_projected_pairs.py +196 -0
  496. anyfesolver/general_contact/multiple_shell_planes.py +226 -0
  497. anyfesolver/general_contact/native_activation_static.py +143 -0
  498. anyfesolver/general_contact/native_checkpoint_results.py +213 -0
  499. anyfesolver/general_contact/native_curve_union.py +268 -0
  500. anyfesolver/general_contact/native_curved_geometry.py +374 -0
  501. anyfesolver/general_contact/native_curved_pair_partition.py +590 -0
  502. anyfesolver/general_contact/native_curved_plane_work.py +864 -0
  503. anyfesolver/general_contact/native_curved_s3_work.py +472 -0
  504. anyfesolver/general_contact/native_event_polynomial.py +164 -0
  505. anyfesolver/general_contact/native_fibre_context.py +173 -0
  506. anyfesolver/general_contact/native_fibre_results.py +74 -0
  507. anyfesolver/general_contact/native_initial_guess.py +122 -0
  508. anyfesolver/general_contact/native_material_activation.py +108 -0
  509. anyfesolver/general_contact/native_material_plane.py +111 -0
  510. anyfesolver/general_contact/native_material_s3.py +209 -0
  511. anyfesolver/general_contact/native_multi_s3_static.py +722 -0
  512. anyfesolver/general_contact/native_normal_angles.py +233 -0
  513. anyfesolver/general_contact/native_pair_error_budget.py +49 -0
  514. anyfesolver/general_contact/native_replay_arithmetic.py +103 -0
  515. anyfesolver/general_contact/native_replay_diagnostics.py +90 -0
  516. anyfesolver/general_contact/native_retained_body_junction.py +99 -0
  517. anyfesolver/general_contact/native_retained_body_pair.py +220 -0
  518. anyfesolver/general_contact/native_retained_body_projection.py +160 -0
  519. anyfesolver/general_contact/native_retained_body_static.py +62 -0
  520. anyfesolver/general_contact/native_retained_cell_pair.py +185 -0
  521. anyfesolver/general_contact/native_retained_curve_cell.py +102 -0
  522. anyfesolver/general_contact/native_retained_line_plane.py +210 -0
  523. anyfesolver/general_contact/native_retained_line_s3.py +440 -0
  524. anyfesolver/general_contact/native_retained_line_s3_work.py +91 -0
  525. anyfesolver/general_contact/native_retained_pair_static.py +845 -0
  526. anyfesolver/general_contact/native_retained_s3_static.py +554 -0
  527. anyfesolver/general_contact/native_retained_static.py +478 -0
  528. anyfesolver/general_contact/native_retained_station.py +222 -0
  529. anyfesolver/general_contact/native_retained_whole_pair.py +2120 -0
  530. anyfesolver/general_contact/native_s3_swept.py +149 -0
  531. anyfesolver/general_contact/native_shell_static_driver.py +144 -0
  532. anyfesolver/general_contact/native_surface_activation.py +391 -0
  533. anyfesolver/general_contact/native_surface_bounds.py +198 -0
  534. anyfesolver/general_contact/native_surface_contributor.py +121 -0
  535. anyfesolver/general_contact/native_surface_crossing.py +81 -0
  536. anyfesolver/general_contact/native_surface_event_sequence.py +320 -0
  537. anyfesolver/general_contact/native_surface_extrema.py +72 -0
  538. anyfesolver/general_contact/native_surface_friction_integral.py +1724 -0
  539. anyfesolver/general_contact/native_surface_front.py +742 -0
  540. anyfesolver/general_contact/native_surface_front_boundary.py +160 -0
  541. anyfesolver/general_contact/native_surface_front_precision.py +78 -0
  542. anyfesolver/general_contact/native_surface_front_work.py +118 -0
  543. anyfesolver/general_contact/native_surface_history.py +334 -0
  544. anyfesolver/general_contact/native_surface_normal.py +324 -0
  545. anyfesolver/general_contact/native_surface_patch.py +213 -0
  546. anyfesolver/general_contact/native_surface_path.py +348 -0
  547. anyfesolver/general_contact/native_surface_quadrature.py +212 -0
  548. anyfesolver/general_contact/native_surface_s3_friction.py +340 -0
  549. anyfesolver/general_contact/native_surface_support.py +776 -0
  550. anyfesolver/general_contact/native_surface_transaction.py +198 -0
  551. anyfesolver/general_contact/native_transient_multi_shell.py +108 -0
  552. anyfesolver/general_contact/native_transient_pair.py +61 -0
  553. anyfesolver/general_contact/native_transient_shell.py +44 -0
  554. anyfesolver/general_contact/normal_s3_skin_path.py +163 -0
  555. anyfesolver/general_contact/overlap.py +443 -0
  556. anyfesolver/general_contact/pair.py +466 -0
  557. anyfesolver/general_contact/patch_broadphase.py +111 -0
  558. anyfesolver/general_contact/patch_mortar.py +593 -0
  559. anyfesolver/general_contact/patch_sliding.py +644 -0
  560. anyfesolver/general_contact/plane_newmark_events.py +278 -0
  561. anyfesolver/general_contact/pointwise_patch.py +288 -0
  562. anyfesolver/general_contact/polynomial_roots.py +312 -0
  563. anyfesolver/general_contact/pressure_basis.py +241 -0
  564. anyfesolver/general_contact/pressure_diagnostics.py +155 -0
  565. anyfesolver/general_contact/pressure_overlay.py +182 -0
  566. anyfesolver/general_contact/pressure_space.py +51 -0
  567. anyfesolver/general_contact/q4_material_checkpoint.py +276 -0
  568. anyfesolver/general_contact/q4_overlap_local_bound.py +1111 -0
  569. anyfesolver/general_contact/q4_q4_overlap_derivatives.py +234 -0
  570. anyfesolver/general_contact/q4_q4_swept_bound.py +58 -0
  571. anyfesolver/general_contact/q4_s3_overlap_derivatives.py +1159 -0
  572. anyfesolver/general_contact/q4_s3_tiny_wedge.py +180 -0
  573. anyfesolver/general_contact/q4_skin_work.py +87 -0
  574. anyfesolver/general_contact/q4_source_mortar_energy.py +181 -0
  575. anyfesolver/general_contact/q4_source_overlap.py +401 -0
  576. anyfesolver/general_contact/q4_target_overlap.py +181 -0
  577. anyfesolver/general_contact/request_identity.py +192 -0
  578. anyfesolver/general_contact/rigid_translation.py +199 -0
  579. anyfesolver/general_contact/runtime.py +27 -0
  580. anyfesolver/general_contact/s3_friction_chart_interval.py +104 -0
  581. anyfesolver/general_contact/s3_friction_coverage.py +165 -0
  582. anyfesolver/general_contact/s3_friction_dyadic_interval.py +39 -0
  583. anyfesolver/general_contact/s3_friction_history_path.py +111 -0
  584. anyfesolver/general_contact/s3_friction_mesh_coverage.py +145 -0
  585. anyfesolver/general_contact/s3_friction_mesh_gap.py +74 -0
  586. anyfesolver/general_contact/s3_friction_mesh_monolithic.py +150 -0
  587. anyfesolver/general_contact/s3_friction_monolithic.py +121 -0
  588. anyfesolver/general_contact/s3_friction_moving_coverage.py +114 -0
  589. anyfesolver/general_contact/s3_friction_pair.py +237 -0
  590. anyfesolver/general_contact/s3_friction_point.py +129 -0
  591. anyfesolver/general_contact/s3_friction_prepared_path.py +254 -0
  592. anyfesolver/general_contact/s3_friction_replay.py +1094 -0
  593. anyfesolver/general_contact/s3_friction_rim_path.py +69 -0
  594. anyfesolver/general_contact/s3_friction_rim_transaction.py +23 -0
  595. anyfesolver/general_contact/s3_friction_static.py +267 -0
  596. anyfesolver/general_contact/s3_friction_swept_gap.py +112 -0
  597. anyfesolver/general_contact/s3_friction_touch.py +94 -0
  598. anyfesolver/general_contact/s3_friction_weak_pressure.py +66 -0
  599. anyfesolver/general_contact/s3_overlap_derivatives.py +220 -0
  600. anyfesolver/general_contact/s3_overlap_hermite_gap.py +180 -0
  601. anyfesolver/general_contact/s3_pair_static.py +343 -0
  602. anyfesolver/general_contact/s3_patch_augmented.py +2056 -0
  603. anyfesolver/general_contact/s3_patch_mortar_energy.py +545 -0
  604. anyfesolver/general_contact/s3_patch_static.py +1725 -0
  605. anyfesolver/general_contact/s3_pressure_hermite_bounds.py +395 -0
  606. anyfesolver/general_contact/s3_pressure_polygon_bounds.py +73 -0
  607. anyfesolver/general_contact/s3_q4_gap_resolution.py +191 -0
  608. anyfesolver/general_contact/s3_q4_overlap_derivatives.py +252 -0
  609. anyfesolver/general_contact/s3_q4_swept.py +56 -0
  610. anyfesolver/general_contact/s3_skin_work.py +101 -0
  611. anyfesolver/general_contact/s3_sliding_friction.py +640 -0
  612. anyfesolver/general_contact/s3_stable_plane_gap.py +43 -0
  613. anyfesolver/general_contact/seed_path_vertex_interval.py +323 -0
  614. anyfesolver/general_contact/semismooth.py +133 -0
  615. anyfesolver/general_contact/semismooth_block.py +147 -0
  616. anyfesolver/general_contact/semismooth_path.py +871 -0
  617. anyfesolver/general_contact/shell_pair_hermite_sweep.py +336 -0
  618. anyfesolver/general_contact/shell_sphere_temporal_bounds.py +305 -0
  619. anyfesolver/general_contact/skin_geometry.py +106 -0
  620. anyfesolver/general_contact/sliding.py +349 -0
  621. anyfesolver/general_contact/sphere.py +691 -0
  622. anyfesolver/general_contact/sphere_temporal_bounds.py +241 -0
  623. anyfesolver/general_contact/static_path.py +2608 -0
  624. anyfesolver/general_contact/static_results_archive.py +140 -0
  625. anyfesolver/general_contact/structural_state_bridge.py +196 -0
  626. anyfesolver/general_contact/supported_schur.py +594 -0
  627. anyfesolver/general_contact/swept_patch_broadphase.py +160 -0
  628. anyfesolver/general_contact/transient.py +2921 -0
  629. anyfesolver/general_contact/transient_results_archive.py +491 -0
  630. anyfesolver/general_contact/triangle_mortar_energy.py +280 -0
  631. anyfesolver/general_contact/triangle_pair_energy.py +211 -0
  632. anyfesolver/general_contact/triangulated_rigid.py +94 -0
  633. anyfesolver/general_contact/triangulated_rigid_static.py +399 -0
  634. anyfesolver/general_contact/warped_q4_plane.py +185 -0
  635. anyfesolver/general_contact/warped_q4_skin.py +302 -0
  636. anyfesolver/general_contact/warped_q4_static.py +331 -0
  637. anyfesolver/impact_performance.py +273 -0
  638. anyfesolver/impact_reduced_assembly.py +294 -0
  639. anyfesolver/imperfections.py +397 -0
  640. anyfesolver/inertia_relief.py +676 -0
  641. anyfesolver/initial_field_state.py +54 -0
  642. anyfesolver/jit_compiler.py +135 -0
  643. anyfesolver/kernel_warmup.py +228 -0
  644. anyfesolver/linalg.py +1002 -0
  645. anyfesolver/marine_contributions.py +634 -0
  646. anyfesolver/marine_coupled_equilibrium.py +292 -0
  647. anyfesolver/marine_equilibrium.py +405 -0
  648. anyfesolver/marine_hydro_coordinates.py +346 -0
  649. anyfesolver/marine_linear.py +549 -0
  650. anyfesolver/marine_link.py +306 -0
  651. anyfesolver/marine_mechanical.py +923 -0
  652. anyfesolver/marine_mooring.py +533 -0
  653. anyfesolver/marine_morison.py +331 -0
  654. anyfesolver/marine_potential_flow.py +403 -0
  655. anyfesolver/marine_rigid.py +397 -0
  656. anyfesolver/marine_seabed.py +122 -0
  657. anyfesolver/mass_properties.py +352 -0
  658. anyfesolver/material_curves.py +52 -0
  659. anyfesolver/materials.py +43 -0
  660. anyfesolver/matrix_assembly.py +7330 -0
  661. anyfesolver/mesh_gen.py +904 -0
  662. anyfesolver/mesh_load_bc_verification.py +612 -0
  663. anyfesolver/modal.py +2494 -0
  664. anyfesolver/nonlinear.py +341 -0
  665. anyfesolver/nonlinear_analysis_diagnostics.py +466 -0
  666. anyfesolver/nonlinear_element_evaluation.py +126 -0
  667. anyfesolver/nonlinear_performance.py +2094 -0
  668. anyfesolver/nonlinear_performance_batch_b.py +1173 -0
  669. anyfesolver/nonlinear_performance_batch_c.py +850 -0
  670. anyfesolver/nonlinear_performance_bootstrap.py +164 -0
  671. anyfesolver/nonlinear_reduced_assembly.py +806 -0
  672. anyfesolver/nonlinear_restart.py +1708 -0
  673. anyfesolver/nonlinear_state.py +2800 -0
  674. anyfesolver/nonlinear_static.py +9407 -0
  675. anyfesolver/outcomes.py +694 -0
  676. anyfesolver/plasticity.py +2087 -0
  677. anyfesolver/plasticity_qualification.py +758 -0
  678. anyfesolver/prepared_static.py +1129 -0
  679. anyfesolver/prepared_static_envelopes.py +389 -0
  680. anyfesolver/prepared_static_loads.py +1180 -0
  681. anyfesolver/prepared_static_measures.py +18 -0
  682. anyfesolver/prepared_static_numeric.py +247 -0
  683. anyfesolver/prepared_static_q4.py +297 -0
  684. anyfesolver/prepared_static_recovery.py +2068 -0
  685. anyfesolver/prepared_static_response.py +1013 -0
  686. anyfesolver/prepared_static_shared.py +226 -0
  687. anyfesolver/prepared_static_snapshot.py +323 -0
  688. anyfesolver/prepared_static_vectorized.py +866 -0
  689. anyfesolver/pressure_regions.py +287 -0
  690. anyfesolver/production_readiness.py +343 -0
  691. anyfesolver/quality_control.py +1487 -0
  692. anyfesolver/quantities.py +1289 -0
  693. anyfesolver/recovery.py +4217 -0
  694. anyfesolver/recovery_batches.py +1985 -0
  695. anyfesolver/recovery_policy.py +205 -0
  696. anyfesolver/recovery_s4.py +289 -0
  697. anyfesolver/recovery_shell_frames.py +102 -0
  698. anyfesolver/reference_cases.py +366 -0
  699. anyfesolver/result_capsule.py +2175 -0
  700. anyfesolver/results.py +752 -0
  701. anyfesolver/runtime.py +9819 -0
  702. anyfesolver/s3_reference_batch.py +1338 -0
  703. anyfesolver/s3_v2c_fast_assembly.py +544 -0
  704. anyfesolver/s3_v2d_fast_assembly.py +447 -0
  705. anyfesolver/s4_validity.py +354 -0
  706. anyfesolver/sections.py +67 -0
  707. anyfesolver/sesam_fem/__init__.py +55 -0
  708. anyfesolver/sesam_fem/__main__.py +80 -0
  709. anyfesolver/sesam_fem/diagnostics.py +5 -0
  710. anyfesolver/sesam_fem/document.py +39 -0
  711. anyfesolver/sesam_fem/exporter.py +9 -0
  712. anyfesolver/sesam_fem/importer.py +228 -0
  713. anyfesolver/sesam_fem/records.py +21 -0
  714. anyfesolver/sesam_fem/schema.py +35 -0
  715. anyfesolver/sesam_fem/sif_importer.py +9 -0
  716. anyfesolver/sesam_fem/validation.py +5 -0
  717. anyfesolver/sestra_deep_diagnostics.py +173 -0
  718. anyfesolver/sestra_mixed_verification.py +146 -0
  719. anyfesolver/sestra_structure_benchmarks.py +270 -0
  720. anyfesolver/sestra_three_case.py +215 -0
  721. anyfesolver/sestra_verification.py +523 -0
  722. anyfesolver/shell_benchmarks.py +367 -0
  723. anyfesolver/shell_formulations/director_field.py +799 -0
  724. anyfesolver/shell_formulations/geometry_provenance.py +921 -0
  725. anyfesolver/shell_formulations/mitc4_plus_d_quality.py +318 -0
  726. anyfesolver/shell_formulations/mitc4_plus_d_reference.py +837 -0
  727. anyfesolver/shell_formulations/mitc4_plus_d_scalar.py +209 -0
  728. anyfesolver/shell_formulations/protocol.py +222 -0
  729. anyfesolver/shell_formulations/q4_common.py +271 -0
  730. anyfesolver/shell_formulations/s4_restricted_policy.py +78 -0
  731. anyfesolver/shell_sections.py +394 -0
  732. anyfesolver/solid_submodel.py +930 -0
  733. anyfesolver/static_batch.py +662 -0
  734. anyfesolver/static_envelopes.py +250 -0
  735. anyfesolver/stiffened_shell.py +388 -0
  736. anyfesolver/submodel_transfer.py +1306 -0
  737. anyfesolver/test_cases.py +610 -0
  738. anyfesolver/threading_policy.py +431 -0
  739. anyfesolver/validation.py +719 -0
  740. anyfesolver/vectorized_beam.py +139 -0
  741. anyfesolver/vectorized_generalized_shell.py +448 -0
  742. anyfesolver/vectorized_hill48.py +956 -0
  743. anyfesolver/vectorized_nonlinear.py +360 -0
  744. anyfesolver/vectorized_stiffness.py +694 -0
  745. anyfesolver-0.5.0a1.dist-info/METADATA +374 -0
  746. anyfesolver-0.5.0a1.dist-info/RECORD +751 -0
  747. anyfesolver-0.5.0a1.dist-info/WHEEL +5 -0
  748. anyfesolver-0.5.0a1.dist-info/licenses/COPYRIGHT +1 -0
  749. anyfesolver-0.5.0a1.dist-info/licenses/LICENSE +373 -0
  750. anyfesolver-0.5.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +32 -0
  751. anyfesolver-0.5.0a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,553 @@
1
+ """Auditable fixed-DOF and linear MPC constraint contracts.
2
+
3
+ ANYfeSolver deliberately supports a restricted affine constraint form::
4
+
5
+ u_slave = sum(a_i * u_master_i) + value
6
+
7
+ Together with prescribed support values this form has a structural rank that
8
+ can be determined without a dense rank-revealing factorization: every valid
9
+ equation owns one distinct dependent DOF. This module validates that contract,
10
+ preserves equation provenance, and provides a common post-solve residual check.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import asdict, dataclass
16
+ from numbers import Real
17
+ from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple
18
+
19
+ import numpy as np
20
+
21
+ if TYPE_CHECKING:
22
+ from .fe_core import FEModel
23
+
24
+
25
+ COEFFICIENT_ATOL = 1.0e-14
26
+ RESIDUAL_RTOL = 1.0e-10
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class ConstraintAuditIssue:
31
+ """One stable, machine-readable constraint diagnostic."""
32
+
33
+ code: str
34
+ severity: str
35
+ message: str
36
+ origin: str = ""
37
+ dof: Optional[int] = None
38
+
39
+ def to_dict(self) -> Dict[str, Any]:
40
+ return asdict(self)
41
+
42
+
43
+ @dataclass(frozen=True, init=False)
44
+ class ConstraintEquation:
45
+ """One affine equation ``sum(coefficient * u[dof]) = rhs``.
46
+
47
+ The public constructor uses ``terms``, ``rhs`` and ``source_id``. The
48
+ first term is the dependent/pivot DOF unless ``dependent_dof`` is supplied
49
+ explicitly. Ordering equations this way preserves the sparse, acyclic
50
+ affine reduction used throughout ANYfeSolver.
51
+
52
+ Legacy normalized names (``coefficients``, ``value`` and ``origin``) stay
53
+ available as read-only aliases and accepted keyword arguments.
54
+ """
55
+
56
+ dependent_dof: int
57
+ coefficients: Tuple[Tuple[int, float], ...]
58
+ value: float
59
+ origin: str
60
+ kind: str
61
+
62
+ def __init__(
63
+ self,
64
+ terms: Optional[Tuple[Tuple[int, float], ...]] = None,
65
+ rhs: float = 0.0,
66
+ source_id: str = "",
67
+ dependent_dof: Optional[int] = None,
68
+ kind: str = "equation",
69
+ *,
70
+ coefficients: Optional[Tuple[Tuple[int, float], ...]] = None,
71
+ value: Optional[float] = None,
72
+ origin: Optional[str] = None,
73
+ ) -> None:
74
+ # Original public positional contract:
75
+ # ConstraintEquation(dependent_dof, coefficients, value, origin, kind)
76
+ if (
77
+ isinstance(terms, (int, np.integer))
78
+ and not isinstance(rhs, Real)
79
+ and isinstance(dependent_dof, str)
80
+ ):
81
+ legacy_dependent = int(terms)
82
+ legacy_terms = rhs
83
+ legacy_value = source_id
84
+ legacy_origin = dependent_dof
85
+ terms = legacy_terms # type: ignore[assignment]
86
+ rhs = legacy_value # type: ignore[assignment]
87
+ source_id = legacy_origin
88
+ dependent_dof = legacy_dependent
89
+ if terms is None:
90
+ terms = coefficients
91
+ if terms is None or len(terms) == 0:
92
+ raise ValueError("ConstraintEquation requires at least one term")
93
+ term_items = terms.items() if isinstance(terms, Mapping) else terms
94
+ normalized = tuple((int(dof), float(coefficient)) for dof, coefficient in term_items)
95
+ pivot = int(normalized[0][0] if dependent_dof is None else dependent_dof)
96
+ if pivot not in {dof for dof, _coefficient in normalized}:
97
+ raise ValueError("dependent_dof must identify one of the equation terms")
98
+ object.__setattr__(self, "dependent_dof", pivot)
99
+ object.__setattr__(self, "coefficients", normalized)
100
+ object.__setattr__(self, "value", float(rhs if value is None else value))
101
+ object.__setattr__(self, "origin", str(source_id if origin is None else origin))
102
+ object.__setattr__(self, "kind", str(kind))
103
+
104
+ @property
105
+ def terms(self) -> Tuple[Tuple[int, float], ...]:
106
+ return self.coefficients
107
+
108
+ @property
109
+ def rhs(self) -> float:
110
+ return self.value
111
+
112
+ @property
113
+ def source_id(self) -> str:
114
+ return self.origin
115
+
116
+ def to_dict(self) -> Dict[str, Any]:
117
+ return {
118
+ "dependent_dof": int(self.dependent_dof),
119
+ "terms": [
120
+ {"dof": int(dof), "coefficient": float(coefficient)}
121
+ for dof, coefficient in self.terms
122
+ ],
123
+ "rhs": float(self.rhs),
124
+ "source_id": self.source_id,
125
+ "kind": self.kind,
126
+ # Compatibility keys retained for existing report consumers.
127
+ "coefficients": [
128
+ {"dof": int(dof), "coefficient": float(coefficient)}
129
+ for dof, coefficient in self.terms
130
+ ],
131
+ "value": float(self.rhs),
132
+ "origin": self.source_id,
133
+ }
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class ConstraintAuditReport:
138
+ """Integrity and structural-rank report for the active constraint system."""
139
+
140
+ status: str
141
+ total_dofs: int
142
+ equation_count: int
143
+ structural_rank: int
144
+ redundant_equations: int
145
+ independent_dofs: int
146
+ fixed_dofs: int
147
+ mpc_slave_dofs: int
148
+ homogeneous: bool
149
+ feasible: bool
150
+ max_dependency_depth: int
151
+ origin_counts: Dict[str, int]
152
+ equations: Tuple[ConstraintEquation, ...]
153
+ issues: Tuple[ConstraintAuditIssue, ...]
154
+
155
+ @property
156
+ def errors(self) -> Tuple[ConstraintAuditIssue, ...]:
157
+ return tuple(issue for issue in self.issues if issue.severity == "error")
158
+
159
+ @property
160
+ def warnings(self) -> Tuple[ConstraintAuditIssue, ...]:
161
+ return tuple(issue for issue in self.issues if issue.severity == "warning")
162
+
163
+ def to_dict(self) -> Dict[str, Any]:
164
+ payload = asdict(self)
165
+ payload["equations"] = [equation.to_dict() for equation in self.equations]
166
+ payload["issues"] = [issue.to_dict() for issue in self.issues]
167
+ payload["error_count"] = len(self.errors)
168
+ payload["warning_count"] = len(self.warnings)
169
+ return payload
170
+
171
+
172
+ @dataclass(frozen=True)
173
+ class _Equation:
174
+ dependent: int
175
+ coefficients: Dict[int, float]
176
+ value: float
177
+ origin: str
178
+ kind: str
179
+
180
+
181
+ def _finite_number(value: Any) -> Optional[float]:
182
+ if isinstance(value, (bool, np.bool_)) or not isinstance(value, Real):
183
+ return None
184
+ try:
185
+ result = float(value)
186
+ except (TypeError, ValueError, OverflowError):
187
+ return None
188
+ return result if np.isfinite(result) else None
189
+
190
+
191
+ def _dof_index(value: Any) -> Optional[int]:
192
+ if isinstance(value, (bool, np.bool_)):
193
+ return None
194
+ try:
195
+ integer = int(value)
196
+ numeric = float(value)
197
+ except (TypeError, ValueError, OverflowError):
198
+ return None
199
+ return integer if np.isfinite(numeric) and numeric == integer else None
200
+
201
+
202
+ def _collect_equations(model: "FEModel") -> Tuple[List[_Equation], List[ConstraintAuditIssue]]:
203
+ total_dofs = int(model.mesh.dof_manager.total_dofs)
204
+ equations: List[_Equation] = []
205
+ issues: List[ConstraintAuditIssue] = []
206
+
207
+ for bc_index, bc in enumerate(model.boundary_conditions):
208
+ name = str(getattr(bc, "name", f"boundary_{bc_index}"))
209
+ origin = f"support:{name}"
210
+ try:
211
+ constrained = bc.get_constrained_dofs(model.mesh.dof_manager)
212
+ except Exception as exc:
213
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"Cannot enumerate support constraints: {exc}", origin))
214
+ continue
215
+ for dof_raw, value_raw in constrained:
216
+ dof = _dof_index(dof_raw)
217
+ if dof is None:
218
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"Support has invalid DOF {dof_raw!r}.", origin))
219
+ continue
220
+ value = _finite_number(value_raw)
221
+ if not 0 <= dof < total_dofs:
222
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"Support DOF {dof} is outside [0, {total_dofs}).", origin, dof))
223
+ continue
224
+ if value is None:
225
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", f"Support DOF {dof} has a non-finite prescribed value.", origin, dof))
226
+ continue
227
+ equations.append(_Equation(dof, {}, value, origin, "support"))
228
+
229
+ # Reduce user equations against prior prescribed/general equations as they
230
+ # are collected. This sparse row-echelon step turns independent rotated
231
+ # coordinate rows into an acyclic affine graph without a dense nullspace
232
+ # factorization (for example two 45-degree local restraints at one node).
233
+ known_relations: Dict[int, _Equation] = {}
234
+ for existing in equations:
235
+ known_relations.setdefault(existing.dependent, existing)
236
+
237
+ for equation_index, equation in enumerate(getattr(model, "constraint_equations", ())):
238
+ source_id = str(getattr(equation, "source_id", "") or f"equation_{equation_index}")
239
+ origin = f"equation:{source_id}"
240
+ terms_raw = getattr(equation, "terms", getattr(equation, "coefficients", ()))
241
+ combined: Dict[int, float] = {}
242
+ valid = True
243
+ try:
244
+ term_items = terms_raw.items() if isinstance(terms_raw, Mapping) else terms_raw
245
+ for dof_raw, coefficient_raw in term_items:
246
+ dof = _dof_index(dof_raw)
247
+ coefficient = _finite_number(coefficient_raw)
248
+ if dof is None or not 0 <= dof < total_dofs:
249
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"Equation has invalid DOF {dof_raw!r}.", origin))
250
+ valid = False
251
+ elif coefficient is None:
252
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", f"Equation coefficient for DOF {dof} is non-finite.", origin, dof))
253
+ valid = False
254
+ elif abs(coefficient) > COEFFICIENT_ATOL:
255
+ combined[dof] = combined.get(dof, 0.0) + coefficient
256
+ except (TypeError, ValueError) as exc:
257
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", f"Equation terms are invalid: {exc}", origin))
258
+ continue
259
+ combined = {
260
+ dof: coefficient
261
+ for dof, coefficient in combined.items()
262
+ if abs(coefficient) > COEFFICIENT_ATOL
263
+ }
264
+ dependent = _dof_index(getattr(equation, "dependent_dof", None))
265
+ value = _finite_number(getattr(equation, "rhs", getattr(equation, "value", 0.0)))
266
+ if not combined:
267
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", "Equation has no non-zero finite terms.", origin))
268
+ continue
269
+ if dependent is None or dependent not in combined:
270
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", "Equation dependent DOF is not a non-zero term.", origin, dependent))
271
+ valid = False
272
+ if value is None:
273
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", "Equation right-hand side is non-finite.", origin, dependent))
274
+ valid = False
275
+ if not valid:
276
+ continue
277
+
278
+ reduced_terms = dict(combined)
279
+ reduced_rhs = float(value)
280
+ while True:
281
+ substituted = False
282
+ for known_dof in tuple(reduced_terms):
283
+ relation = known_relations.get(known_dof)
284
+ if relation is None:
285
+ continue
286
+ coefficient = reduced_terms.pop(known_dof)
287
+ reduced_rhs -= coefficient * relation.value
288
+ for master, master_coefficient in relation.coefficients.items():
289
+ reduced_terms[master] = (
290
+ reduced_terms.get(master, 0.0)
291
+ + coefficient * master_coefficient
292
+ )
293
+ reduced_terms = {
294
+ dof: item
295
+ for dof, item in reduced_terms.items()
296
+ if abs(item) > COEFFICIENT_ATOL
297
+ }
298
+ substituted = True
299
+ break
300
+ if not substituted:
301
+ break
302
+
303
+ if not reduced_terms:
304
+ scale = max(abs(float(value)), 1.0)
305
+ if abs(reduced_rhs) <= RESIDUAL_RTOL * scale:
306
+ issues.append(
307
+ ConstraintAuditIssue(
308
+ "CONSTRAINT007",
309
+ "warning",
310
+ "Equation is redundant after affine reduction.",
311
+ origin,
312
+ dependent,
313
+ )
314
+ )
315
+ else:
316
+ issues.append(
317
+ ConstraintAuditIssue(
318
+ "CONSTRAINT005",
319
+ "error",
320
+ f"Equation is inconsistent after affine reduction (remaining rhs {reduced_rhs:.6g}).",
321
+ origin,
322
+ dependent,
323
+ )
324
+ )
325
+ continue
326
+
327
+ if dependent not in reduced_terms:
328
+ # The requested pivot may have been eliminated by an earlier row.
329
+ # Preserve original term order when selecting the next free pivot.
330
+ dependent = next(
331
+ (dof for dof, _coefficient in combined.items() if dof in reduced_terms),
332
+ next(iter(reduced_terms)),
333
+ )
334
+ pivot = reduced_terms.pop(int(dependent))
335
+ # sum(c_i*u_i)=rhs -> u_dep=rhs/c_dep-sum(c_i/c_dep*u_i)
336
+ masters = {dof: -coefficient / pivot for dof, coefficient in reduced_terms.items()}
337
+ normalized = _Equation(
338
+ int(dependent),
339
+ masters,
340
+ reduced_rhs / pivot,
341
+ origin,
342
+ "equation",
343
+ )
344
+ equations.append(normalized)
345
+ known_relations[int(dependent)] = normalized
346
+
347
+ for element_id, element in model.mesh.elements.items():
348
+ getter = getattr(element, "get_mpc_constraints", None)
349
+ if getter is None:
350
+ continue
351
+ try:
352
+ constraints = getter(model.mesh) or ()
353
+ except Exception as exc:
354
+ origin = f"mpc:element:{int(element_id)}"
355
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"Cannot enumerate MPC constraints: {exc}", origin))
356
+ continue
357
+ for index, raw in enumerate(constraints):
358
+ label = str(raw.get("label", f"constraint_{index}"))
359
+ origin = f"mpc:{int(element_id)}:{label}"
360
+ dependent = _dof_index(raw.get("slave"))
361
+ if dependent is None:
362
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", "MPC has an invalid slave DOF.", origin))
363
+ continue
364
+ if not 0 <= dependent < total_dofs:
365
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"MPC slave DOF {dependent} is outside [0, {total_dofs}).", origin, dependent))
366
+ continue
367
+ value = _finite_number(raw.get("value", 0.0))
368
+ if value is None:
369
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", f"MPC slave DOF {dependent} has a non-finite affine value.", origin, dependent))
370
+ continue
371
+ masters: Dict[int, float] = {}
372
+ valid = True
373
+ raw_masters = raw.get("masters", {})
374
+ if not isinstance(raw_masters, Mapping):
375
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", "MPC masters must be a mapping.", origin, dependent))
376
+ continue
377
+ for master_raw, coefficient_raw in raw_masters.items():
378
+ master = _dof_index(master_raw)
379
+ if master is None:
380
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"MPC has invalid master DOF {master_raw!r}.", origin, dependent))
381
+ valid = False
382
+ continue
383
+ coefficient = _finite_number(coefficient_raw)
384
+ if not 0 <= master < total_dofs:
385
+ issues.append(ConstraintAuditIssue("CONSTRAINT001", "error", f"MPC master DOF {master} is outside [0, {total_dofs}).", origin, master))
386
+ valid = False
387
+ elif coefficient is None:
388
+ issues.append(ConstraintAuditIssue("CONSTRAINT004", "error", f"MPC coefficient for master DOF {master} is non-finite.", origin, master))
389
+ valid = False
390
+ elif abs(coefficient) > COEFFICIENT_ATOL:
391
+ masters[master] = masters.get(master, 0.0) + coefficient
392
+ masters = {dof: coefficient for dof, coefficient in masters.items() if abs(coefficient) > COEFFICIENT_ATOL}
393
+ if dependent in masters:
394
+ issues.append(ConstraintAuditIssue("CONSTRAINT003", "error", f"MPC slave DOF {dependent} references itself.", origin, dependent))
395
+ valid = False
396
+ if valid:
397
+ equations.append(_Equation(dependent, masters, value, origin, "mpc"))
398
+
399
+ return equations, issues
400
+
401
+
402
+ def audit_constraints(model: "FEModel") -> ConstraintAuditReport:
403
+ """Audit fixed supports and affine MPCs without assembling FE matrices."""
404
+ total_dofs = int(model.mesh.dof_manager.total_dofs)
405
+ equations, issues = _collect_equations(model)
406
+ owners: Dict[int, _Equation] = {}
407
+ redundant = 0
408
+
409
+ for equation in equations:
410
+ previous = owners.get(equation.dependent)
411
+ if previous is None:
412
+ owners[equation.dependent] = equation
413
+ continue
414
+ if previous.kind == equation.kind == "support" and np.isclose(previous.value, equation.value):
415
+ redundant += 1
416
+ issues.append(ConstraintAuditIssue("CONSTRAINT002", "warning", f"DOF {equation.dependent} has a duplicate prescribed constraint.", equation.origin, equation.dependent))
417
+ else:
418
+ issues.append(ConstraintAuditIssue("CONSTRAINT002", "error", f"DOF {equation.dependent} has multiple dependent definitions ({previous.origin}, {equation.origin}).", equation.origin, equation.dependent))
419
+
420
+ mpc_by_slave = {
421
+ dof: equation
422
+ for dof, equation in owners.items()
423
+ if equation.kind != "support"
424
+ }
425
+ visiting: Dict[int, int] = {}
426
+ depths: Dict[int, int] = {}
427
+
428
+ def visit(dof: int, path: Tuple[int, ...] = ()) -> int:
429
+ state = visiting.get(dof, 0)
430
+ if state == 1:
431
+ cycle = path[path.index(dof):] + (dof,) if dof in path else path + (dof,)
432
+ equation = mpc_by_slave[dof]
433
+ issues.append(ConstraintAuditIssue("CONSTRAINT003", "error", f"Circular MPC dependency detected: {' -> '.join(map(str, cycle))}.", equation.origin, dof))
434
+ return 0
435
+ if state == 2:
436
+ return depths[dof]
437
+ visiting[dof] = 1
438
+ equation = mpc_by_slave[dof]
439
+ child_depths = [visit(master, path + (dof,)) for master in equation.coefficients if master in mpc_by_slave]
440
+ depth = 1 + max(child_depths, default=0)
441
+ depths[dof] = depth
442
+ visiting[dof] = 2
443
+ return depth
444
+
445
+ for slave in mpc_by_slave:
446
+ if visiting.get(slave, 0) == 0:
447
+ visit(slave)
448
+
449
+ error_count = sum(issue.severity == "error" for issue in issues)
450
+ dependent_count = len(owners)
451
+ fixed_count = sum(equation.kind == "support" for equation in owners.values())
452
+ mpc_count = sum(equation.kind != "support" for equation in owners.values())
453
+ homogeneous = all(abs(equation.value) <= COEFFICIENT_ATOL for equation in equations)
454
+ origin_counts: Dict[str, int] = {}
455
+ for equation in equations:
456
+ origin_counts[equation.kind] = origin_counts.get(equation.kind, 0) + 1
457
+ status = "invalid" if error_count else ("warning" if issues else "ok")
458
+ normalized_equations = tuple(
459
+ ConstraintEquation(
460
+ dependent_dof=equation.dependent,
461
+ coefficients=((equation.dependent, 1.0),)
462
+ + tuple(sorted((master, -coefficient) for master, coefficient in equation.coefficients.items())),
463
+ value=equation.value,
464
+ origin=equation.origin,
465
+ kind=equation.kind,
466
+ )
467
+ for equation in equations
468
+ )
469
+ return ConstraintAuditReport(
470
+ status=status,
471
+ total_dofs=total_dofs,
472
+ equation_count=len(equations),
473
+ structural_rank=dependent_count if not error_count else max(0, dependent_count),
474
+ redundant_equations=redundant,
475
+ independent_dofs=max(total_dofs - dependent_count, 0),
476
+ fixed_dofs=fixed_count,
477
+ mpc_slave_dofs=mpc_count,
478
+ homogeneous=homogeneous,
479
+ feasible=not bool(error_count),
480
+ max_dependency_depth=max(depths.values(), default=0),
481
+ origin_counts=origin_counts,
482
+ equations=normalized_equations,
483
+ issues=tuple(issues),
484
+ )
485
+
486
+
487
+ def constraint_residual_summary(
488
+ model: "FEModel",
489
+ displacements: np.ndarray,
490
+ *,
491
+ homogeneous_variation: bool = False,
492
+ affine_scale: float = 1.0,
493
+ ) -> Dict[str, Any]:
494
+ """Return normalized support/MPC residuals for one vector or mode matrix.
495
+
496
+ ``affine_scale`` evaluates a proportional prescribed-displacement path,
497
+ where every affine right-hand side is multiplied by the current path
498
+ factor. Eigenvector checks still use ``homogeneous_variation=True``.
499
+ """
500
+ values = np.asarray(displacements, dtype=float)
501
+ if values.ndim == 1:
502
+ values = values.reshape(-1, 1)
503
+ if values.ndim != 2:
504
+ raise ValueError("constraint residual input must be a vector or 2D matrix")
505
+ equations, collection_issues = _collect_equations(model)
506
+ total_dofs = int(model.mesh.dof_manager.total_dofs)
507
+ if values.shape[0] != total_dofs:
508
+ raise ValueError(f"constraint residual input has {values.shape[0]} rows; expected {total_dofs}")
509
+
510
+ max_absolute = 0.0
511
+ max_relative = 0.0
512
+ worst_origin = ""
513
+ residual_l2 = 0.0
514
+ for equation in equations:
515
+ prescribed = (
516
+ 0.0 if homogeneous_variation else float(affine_scale) * equation.value
517
+ )
518
+ residual = values[equation.dependent, :] - prescribed
519
+ scale = np.maximum(np.abs(values[equation.dependent, :]), abs(prescribed))
520
+ for master, coefficient in equation.coefficients.items():
521
+ residual = residual - coefficient * values[master, :]
522
+ scale = scale + abs(coefficient) * np.abs(values[master, :])
523
+ absolute = float(np.max(np.abs(residual), initial=0.0))
524
+ relative = float(np.max(np.abs(residual) / np.maximum(scale, 1.0), initial=0.0))
525
+ residual_l2 += float(np.dot(residual, residual))
526
+ if relative >= max_relative:
527
+ max_relative = relative
528
+ max_absolute = absolute
529
+ worst_origin = equation.origin
530
+ passed = not collection_issues and max_relative <= RESIDUAL_RTOL
531
+ return {
532
+ "status": "passed" if passed else "failed",
533
+ "equation_count": len(equations),
534
+ "vector_count": int(values.shape[1]),
535
+ "max_absolute_residual": max_absolute,
536
+ "max_relative_residual": max_relative,
537
+ "residual_l2_norm": float(np.sqrt(residual_l2)),
538
+ "relative_tolerance": RESIDUAL_RTOL,
539
+ "worst_origin": worst_origin,
540
+ "collection_issue_count": len(collection_issues),
541
+ "homogeneous_variation": bool(homogeneous_variation),
542
+ "affine_scale": 0.0 if homogeneous_variation else float(affine_scale),
543
+ "issue_code": None if passed else "CONSTRAINT006",
544
+ }
545
+
546
+
547
+ def require_valid_constraints(model: "FEModel") -> ConstraintAuditReport:
548
+ """Return the audit or raise before matrix reduction for an invalid model."""
549
+ report = audit_constraints(model)
550
+ if report.errors:
551
+ details = "; ".join(f"{issue.code}: {issue.message}" for issue in report.errors)
552
+ raise ValueError(f"Invalid constraint system: {details}")
553
+ return report