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,545 @@
1
+ """Bounded moving S3 patch mortar penalty with shared material-node pressure."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ import numpy as np
8
+
9
+ from .moving import _has_shared_edge_transition
10
+ from .overlap import PlanarFace, planar_projected_overlap
11
+ from .q4_source_mortar_energy import MovingQ4PrimalMortarPenalty
12
+ from .q4_source_overlap import projected_q4_source_face
13
+ from .triangle_mortar_energy import MovingS3PrimalMortarPenalty
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class S3PatchFace:
18
+ node_ids: tuple[int, int, int]
19
+ reference_positions: np.ndarray
20
+
21
+ def __post_init__(self):
22
+ nodes = tuple(self.node_ids)
23
+ if (len(nodes) not in {3, 4} or len(set(nodes)) != len(nodes)
24
+ or any(type(node) is not int or node <= 0 for node in nodes)):
25
+ raise ValueError("shell patch face needs three or four distinct material nodes")
26
+ face = PlanarFace((1, 1), self.reference_positions)
27
+ if len(face.corners) != len(nodes):
28
+ raise ValueError("shell patch face topology and geometry disagree")
29
+ object.__setattr__(self, "node_ids", nodes)
30
+ object.__setattr__(self, "reference_positions", face.corners)
31
+
32
+
33
+ @dataclass(frozen=True)
34
+ class MovingS3PatchMortarState:
35
+ energy: float
36
+ reference_support: np.ndarray
37
+ reference_weighted_gap: np.ndarray
38
+ normalized_gap: np.ndarray
39
+ pressure: np.ndarray
40
+ pressure_gram: np.ndarray
41
+ overlap_area: float
42
+ reference_overlap_area: float
43
+ minimum_physical_gap: float | None
44
+ overlap_signature: tuple[int, ...]
45
+ overlapping_pairs: int
46
+ weighted_gap_integration_error: float = 0.0
47
+ integration_triangles: int = 0
48
+ area_integration_error: float = 0.0
49
+ # Disposable same-pose float evaluations. These remain independent of
50
+ # the Jet2 integration used to check the differentiated work values.
51
+ pair_states: tuple[object, ...] | None = None
52
+
53
+ @property
54
+ def active_pressure_dofs(self):
55
+ return int(np.count_nonzero(self.pressure))
56
+
57
+
58
+ @dataclass(frozen=True)
59
+ class MovingS3PatchMortarWork:
60
+ state: MovingS3PatchMortarState
61
+ residual: np.ndarray
62
+ tangent: np.ndarray | None
63
+ energy_evaluations: int
64
+ tie_resolution_relative_error: float | None = None
65
+
66
+
67
+ class MovingS3PatchPrimalMortarPenalty:
68
+ """Aggregate pair integrals before normalizing shared source P1 gaps."""
69
+
70
+ def __init__(self, source_faces: tuple[S3PatchFace, ...],
71
+ target_faces: tuple[S3PatchFace, ...], stiffness: float,
72
+ *, difference_step: float,
73
+ maximum_energy_evaluations: int = 1500,
74
+ q4_weighted_gap_tolerance: float | None = None,
75
+ maximum_q4_integration_triangles: int | None = None,
76
+ q4_source_area_tolerance: float | None = None,
77
+ q4_source_weighted_gap_tolerance: float | None = None,
78
+ maximum_q4_source_integration_triangles: int | None = None,
79
+ q4_source_derivative_tolerances: tuple[float | None, ...] | None = None,
80
+ differentiation: str = "global",
81
+ maximum_candidate_pairs: int = 4,
82
+ pair_broadphase: bool = True,
83
+ _full_face_monolithic_s3: bool = False):
84
+ self.source_faces = tuple(source_faces)
85
+ self.target_faces = tuple(target_faces)
86
+ if differentiation not in {"global", "pair_local", "jet2_s3", "jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"}:
87
+ raise ValueError("S3 patch differentiation mode is invalid")
88
+ self.differentiation = differentiation
89
+ if type(pair_broadphase) is not bool:
90
+ raise ValueError("patch pair broad phase selection must be boolean")
91
+ self.pair_broadphase = pair_broadphase
92
+ if (type(maximum_candidate_pairs) is not int or maximum_candidate_pairs < 1
93
+ or len(self.source_faces)*len(self.target_faces) > maximum_candidate_pairs):
94
+ raise MemoryError("S3 patch exceeds declared candidate-pair budget")
95
+ q4_pair = (len(self.source_faces) == len(self.target_faces) == 1
96
+ and len(self.source_faces[0].node_ids) == 4
97
+ and len(self.target_faces[0].node_ids) == 4)
98
+ bounded = (1 <= len(self.source_faces) <= 2
99
+ and 1 <= len(self.target_faces) <= 2
100
+ and (len(self.source_faces)+len(self.target_faces) >= 3
101
+ or q4_pair))
102
+ refined_s3 = (differentiation in {"pair_local", "jet2_s3"}
103
+ and len(self.source_faces)+len(self.target_faces) >= 3
104
+ and all(len(face.node_ids) == 3
105
+ for face in (*self.source_faces, *self.target_faces)))
106
+ if type(_full_face_monolithic_s3) is not bool:
107
+ raise TypeError("full-face S3 internal admission must be boolean")
108
+ if _full_face_monolithic_s3:
109
+ if (differentiation != "jet2_s3"
110
+ or len(self.source_faces) != 1 or len(self.target_faces) != 1
111
+ or any(len(face.node_ids) != 3 for face in (*self.source_faces,*self.target_faces))):
112
+ raise ValueError("internal monolithic S3 admission requires one S3 face per side")
113
+ refined_s3=True
114
+ refined_q4 = (differentiation in {"pair_local", "jet2_q4_s3"}
115
+ and len(self.source_faces) >= 2
116
+ and all(len(face.node_ids) == 4 for face in self.source_faces)
117
+ and all(len(face.node_ids) == 3 for face in self.target_faces))
118
+ refined_s3_q4 = (differentiation == "jet2_s3_q4"
119
+ and len(self.source_faces) == 2 and len(self.target_faces) == 1
120
+ and all(len(face.node_ids) == 3 for face in self.source_faces)
121
+ and len(self.target_faces[0].node_ids) == 4)
122
+ refined_q4_q4 = (differentiation == "jet2_q4_q4"
123
+ and len(self.source_faces) >= 1 and len(self.target_faces) >= 1
124
+ and len(self.source_faces)+len(self.target_faces) >= 3
125
+ and all(len(face.node_ids) == 4 for face in (*self.source_faces, *self.target_faces)))
126
+ refined = refined_s3 or refined_q4 or refined_s3_q4 or refined_q4_q4
127
+ if differentiation == "jet2_q4_q4" and not refined_q4_q4:
128
+ raise ValueError("Q4/Q4 Jet2 needs original Q4 faces and at least three faces")
129
+ if not (bounded or refined):
130
+ raise ValueError("development shell patch needs three faces or one Q4/Q4 pair")
131
+ if differentiation in {"pair_local", "jet2_s3", "jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"} and not refined:
132
+ raise ValueError("local differentiation needs S3 faces or Q4 source/S3 target faces")
133
+ if differentiation == "jet2_s3" and not refined_s3:
134
+ raise ValueError("Jet2 overlap derivatives need at least three S3 faces")
135
+ if differentiation == "jet2_q4_s3" and not refined_q4:
136
+ raise ValueError("Jet2 Q4/S3 overlap derivatives need a refined Q4/S3 patch")
137
+ if differentiation in {"jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"} and (
138
+ q4_source_derivative_tolerances is None
139
+ or len(q4_source_derivative_tolerances) != 4
140
+ or any(value is None or not np.isfinite(value) or value <= 0.0
141
+ for value in q4_source_derivative_tolerances)
142
+ ):
143
+ raise ValueError("Jet2 Q4/S3 overlap derivatives need four positive derivative tolerances")
144
+ if differentiation == "jet2_s3_q4" and not refined_s3_q4:
145
+ raise ValueError("S3/Q4 Jet2 needs two source S3 and one original target Q4")
146
+ if differentiation == "jet2_s3_q4" and any(value is None or value <= 0.
147
+ for value in (q4_source_area_tolerance, q4_source_weighted_gap_tolerance,
148
+ maximum_q4_source_integration_triangles)):
149
+ raise ValueError("S3/Q4 Jet2 needs explicit integration controls")
150
+ source_q4 = all(len(face.node_ids) == 4 for face in self.source_faces)
151
+ if not source_q4 and any(len(face.node_ids) != 3 for face in self.source_faces):
152
+ raise ValueError("development patch pressure side needs S3 triangles or Q4 faces")
153
+ self.source_node_ids = tuple(sorted({node for face in self.source_faces
154
+ for node in face.node_ids}))
155
+ self.target_node_ids = tuple(sorted({node for face in self.target_faces
156
+ for node in face.node_ids}))
157
+ if set(self.source_node_ids) & set(self.target_node_ids):
158
+ raise ValueError("S3 patch sides must have disjoint material nodes")
159
+ self.reference_source = self._unique_reference(
160
+ self.source_faces, self.source_node_ids,
161
+ )
162
+ self.reference_target = self._unique_reference(
163
+ self.target_faces, self.target_node_ids,
164
+ )
165
+ self.source_face_indices = tuple(np.asarray([
166
+ self.source_node_ids.index(node) for node in face.node_ids
167
+ ], dtype=np.intp) for face in self.source_faces)
168
+ self.target_face_indices = tuple(np.asarray([
169
+ self.target_node_ids.index(node) for node in face.node_ids
170
+ ], dtype=np.intp) for face in self.target_faces)
171
+ self.stiffness = float(stiffness)
172
+ self.difference_step = float(difference_step)
173
+ self.q4_source_area_tolerance = q4_source_area_tolerance
174
+ self.q4_source_weighted_gap_tolerance = q4_source_weighted_gap_tolerance
175
+ self.maximum_q4_source_integration_triangles = maximum_q4_source_integration_triangles
176
+ self.q4_source_derivative_tolerances = q4_source_derivative_tolerances
177
+ if (type(maximum_energy_evaluations) is not int
178
+ or maximum_energy_evaluations < 1):
179
+ raise ValueError("S3 patch energy evaluation budget must be positive")
180
+ self.maximum_energy_evaluations = maximum_energy_evaluations
181
+ self.n_coordinates = 3*(len(self.source_node_ids)+len(self.target_node_ids))
182
+ self.required_hessian_evaluations = (
183
+ 1+2*self.n_coordinates**2 if differentiation == "global" else
184
+ 3*self._candidate_evaluation_count(self._candidate_pair_indices(
185
+ self.reference_source, self.reference_target))
186
+ if differentiation in {"jet2_s3", "jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"} else
187
+ sum(2+2*(3*(len(source.node_ids)+len(target.node_ids)))**2
188
+ for source in self.source_faces for target in self.target_faces)
189
+ )
190
+ if self.required_hessian_evaluations > self.maximum_energy_evaluations:
191
+ raise MemoryError(
192
+ "S3 patch Hessian exceeds declared energy evaluation budget"
193
+ )
194
+ self.pair_laws = tuple(
195
+ MovingQ4PrimalMortarPenalty(
196
+ source.reference_positions, target.reference_positions,
197
+ self.stiffness, difference_step=self.difference_step,
198
+ maximum_energy_evaluations=self.maximum_energy_evaluations,
199
+ area_tolerance=q4_source_area_tolerance,
200
+ weighted_gap_tolerance=q4_source_weighted_gap_tolerance,
201
+ maximum_integration_triangles=maximum_q4_source_integration_triangles,
202
+ ) if len(source.node_ids) == 4 else
203
+ MovingS3PrimalMortarPenalty(
204
+ source.reference_positions, target.reference_positions,
205
+ self.stiffness, difference_step=self.difference_step,
206
+ maximum_energy_evaluations=self.maximum_energy_evaluations,
207
+ q4_weighted_gap_tolerance=q4_weighted_gap_tolerance,
208
+ maximum_q4_integration_triangles=maximum_q4_integration_triangles,
209
+ )
210
+ for source in self.source_faces for target in self.target_faces
211
+ )
212
+ self._check_same_side_overlap(self.reference_source, self.source_face_indices)
213
+ self._check_same_side_overlap(self.reference_target, self.target_face_indices)
214
+
215
+ def _candidate_evaluation_count(self, candidate_indices: set[int] | None) -> int:
216
+ return (len(self.source_faces)*len(self.target_faces)
217
+ if candidate_indices is None else len(candidate_indices))
218
+
219
+ def _check_energy_evaluation_budget(self, evaluations: int) -> None:
220
+ if evaluations > self.maximum_energy_evaluations:
221
+ raise MemoryError("S3 patch differentiation budget exhausted")
222
+
223
+ def _preflight_jet2_candidates(self, candidate_indices: set[int] | None) -> None:
224
+ if self.differentiation in {"jet2_s3", "jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"}:
225
+ # Reserve a base float pass, a fallback float pass and one AD
226
+ # pass for every conservative candidate. Tiny-wedge verification
227
+ # consumes the remaining budget under its own runtime guard.
228
+ self._check_energy_evaluation_budget(
229
+ 3*self._candidate_evaluation_count(candidate_indices))
230
+
231
+ @staticmethod
232
+ def _unique_reference(faces: tuple[S3PatchFace, ...],
233
+ node_ids: tuple[int, ...]) -> np.ndarray:
234
+ positions: dict[int, np.ndarray] = {}
235
+ scale = max(1.0, *(float(np.max(np.abs(face.reference_positions)))
236
+ for face in faces))
237
+ for face in faces:
238
+ for node, position in zip(face.node_ids, face.reference_positions):
239
+ if node in positions and (float(np.linalg.norm(positions[node]-position))
240
+ > 1e-12*scale):
241
+ raise ValueError("shared S3 patch node has inconsistent physical skin position")
242
+ positions[node] = position
243
+ return np.asarray([positions[node] for node in node_ids], dtype=float)
244
+
245
+ @staticmethod
246
+ def _check_same_side_overlap(positions: np.ndarray,
247
+ indices: tuple[np.ndarray, ...]) -> None:
248
+ scale = max(1.0, float(np.max(np.abs(positions))))
249
+ checked = []
250
+ for face_index, nodes in enumerate(indices):
251
+ face_positions = positions[nodes]
252
+ # Validate every face, including those later excluded by the
253
+ # conservative projected bound.
254
+ if len(face_positions) == 4:
255
+ face, normal = projected_q4_source_face(face_positions)
256
+ else:
257
+ face = PlanarFace((1, face_index+1), face_positions)
258
+ normal = np.cross(face_positions[1]-face_positions[0],
259
+ face_positions[2]-face_positions[0])
260
+ normal /= np.linalg.norm(normal)
261
+ checked.append((face, normal))
262
+ if len(indices) < 2:
263
+ return
264
+ margin = 64.0*np.finfo(float).eps*scale
265
+ # A projected overlap can occur at any separation along the first
266
+ # face normal. Query a conservative world-space box around that whole
267
+ # normal prism, then retain the original exact projected check.
268
+ from .contact_search import ContactAABBIndex
269
+
270
+ face_boxes = np.asarray([
271
+ np.r_[np.min(positions[nodes], axis=0),
272
+ np.max(positions[nodes], axis=0)]
273
+ for nodes in indices
274
+ ])
275
+ search = ContactAABBIndex(
276
+ tuple(("same_side_face", i) for i in range(len(indices))),
277
+ face_boxes,
278
+ )
279
+ scene_min = np.min(positions, axis=0)
280
+ scene_max = np.max(positions, axis=0)
281
+ scene_corners = np.asarray([
282
+ (x, y, z) for x in (scene_min[0], scene_max[0])
283
+ for y in (scene_min[1], scene_max[1])
284
+ for z in (scene_min[2], scene_max[2])
285
+ ])
286
+ for first_index, (first, normal) in enumerate(checked):
287
+ tangent = first.corners[1]-first.corners[0]
288
+ tangent /= np.linalg.norm(tangent)
289
+ binormal = np.cross(normal, tangent)
290
+ origin = first.corners[0]
291
+ first_relative = positions[indices[first_index]]-origin
292
+ first_xy = np.column_stack((first_relative@tangent,
293
+ first_relative@binormal))
294
+ first_min = np.min(first_xy, axis=0)
295
+ first_max = np.max(first_xy, axis=0)
296
+ normal_coordinates = (scene_corners-origin) @ normal
297
+ normal_limits = (np.min(normal_coordinates)-margin,
298
+ np.max(normal_coordinates)+margin)
299
+ prism_corners = np.asarray([
300
+ origin + a*tangent + b*binormal + c*normal
301
+ for a in (first_min[0]-margin, first_max[0]+margin)
302
+ for b in (first_min[1]-margin, first_max[1]+margin)
303
+ for c in normal_limits
304
+ ])
305
+ prism_box = np.r_[np.min(prism_corners, axis=0),
306
+ np.max(prism_corners, axis=0)]
307
+ candidate_indices = sorted(
308
+ key[1] for key in search.query(prism_box, padding=4*margin)
309
+ if key[1] > first_index
310
+ )
311
+ for second_index in candidate_indices:
312
+ second_positions = positions[indices[second_index]]
313
+ second_relative = second_positions-origin
314
+ second_xy = np.column_stack((second_relative@tangent,
315
+ second_relative@binormal))
316
+ if np.any(np.max(second_xy, axis=0) < first_min-margin) or np.any(
317
+ np.min(second_xy, axis=0) > first_max+margin):
318
+ continue
319
+ projected = second_positions - (
320
+ second_relative @ normal
321
+ )[:, None]*normal
322
+ second = PlanarFace((1, second_index+1), projected)
323
+ overlap = planar_projected_overlap(first, second)
324
+ if overlap is not None and overlap.area > 1e-12*scale**2:
325
+ raise ValueError("S3 patch has overlapping faces on one side")
326
+
327
+ def evaluate(self, current_source: np.ndarray,
328
+ current_target: np.ndarray) -> MovingS3PatchMortarState:
329
+ source = np.asarray(current_source, dtype=float)
330
+ target = np.asarray(current_target, dtype=float)
331
+ if (source.shape != self.reference_source.shape
332
+ or target.shape != self.reference_target.shape
333
+ or not np.all(np.isfinite(source))
334
+ or not np.all(np.isfinite(target))):
335
+ raise ValueError("S3 patch current coordinates have invalid size or values")
336
+ self._check_same_side_overlap(source, self.source_face_indices)
337
+ self._check_same_side_overlap(target, self.target_face_indices)
338
+ candidate_indices = self._candidate_pair_indices(source, target)
339
+ self._preflight_jet2_candidates(candidate_indices)
340
+ support = np.zeros(len(self.source_node_ids))
341
+ weighted_gap = np.zeros_like(support)
342
+ gram = np.zeros((len(support), len(support)))
343
+ overlap_area = reference_overlap_area = 0.0
344
+ minimum = None
345
+ signature: list[int] = []
346
+ overlapping_pairs = 0
347
+ weighted_error = 0.0
348
+ integration_triangles = 0
349
+ area_error = 0.0
350
+ pair_states = []
351
+ evaluations = 0
352
+ for index, law in enumerate(self.pair_laws):
353
+ if candidate_indices is not None and index not in candidate_indices:
354
+ pair_states.append(None)
355
+ signature.append(0)
356
+ continue
357
+ source_face = index // len(self.target_faces)
358
+ target_face = index % len(self.target_faces)
359
+ evaluations += 1
360
+ if self.differentiation in {"jet2_s3", "jet2_q4_s3", "jet2_s3_q4", "jet2_q4_q4"}:
361
+ self._check_energy_evaluation_budget(evaluations)
362
+ state = law.evaluate(source[self.source_face_indices[source_face]],
363
+ target[self.target_face_indices[target_face]])
364
+ pair_states.append(state)
365
+ signature.append(state.overlap_vertices)
366
+ if state.overlap_vertices == 0:
367
+ continue
368
+ overlapping_pairs += 1
369
+ weighted_error += state.weighted_gap_integration_error
370
+ integration_triangles += state.integration_triangles
371
+ area_error += getattr(state, "area_integration_error", 0.0)
372
+ dofs = self.source_face_indices[source_face]
373
+ support[dofs] += state.reference_support
374
+ weighted_gap[dofs] += state.reference_weighted_gap
375
+ gram[np.ix_(dofs, dofs)] += state.pressure_gram
376
+ overlap_area += state.overlap_area
377
+ reference_overlap_area += state.reference_overlap_area
378
+ sampled = (state.minimum_sampled_gap if len(self.source_face_indices[source_face]) == 4
379
+ else state.minimum_physical_gap)
380
+ minimum = (sampled if minimum is None else min(minimum, sampled))
381
+ normalized = np.zeros_like(support)
382
+ supported = support > 0.0
383
+ normalized[supported] = weighted_gap[supported]/support[supported]
384
+ pressure = np.zeros_like(support)
385
+ pressure[supported] = self.stiffness*np.maximum(-normalized[supported], 0.0)
386
+ energy = 0.5*self.stiffness*float(
387
+ support @ np.minimum(normalized, 0.0)**2
388
+ )
389
+ return MovingS3PatchMortarState(
390
+ energy, support, weighted_gap, normalized, pressure, gram,
391
+ overlap_area, reference_overlap_area, minimum,
392
+ tuple(signature), overlapping_pairs,
393
+ weighted_error, integration_triangles, area_error,
394
+ tuple(pair_states),
395
+ )
396
+
397
+ def _candidate_pair_indices(self, source: np.ndarray,
398
+ target: np.ndarray) -> set[int] | None:
399
+ """Conservatively bound target faces projected along each source normal.
400
+
401
+ The source Q4 projection is the same four-corner plane used by the
402
+ exact mortar kernel. Its bilinear interior stays in the convex hull
403
+ of those corners. A target point whose projection can enter that
404
+ hull lies in the full target-depth prism used for the tree query.
405
+ Inclusive padded boxes retain zero-area touching branches.
406
+ """
407
+ if (not self.pair_broadphase
408
+ or len(self.source_faces)*len(self.target_faces) <= 64):
409
+ return None
410
+ from .contact_search import ContactAABBIndex
411
+
412
+ target_boxes = np.asarray([
413
+ np.r_[np.min(target[nodes], axis=0),
414
+ np.max(target[nodes], axis=0)]
415
+ for nodes in self.target_face_indices
416
+ ])
417
+ search = ContactAABBIndex(
418
+ tuple(("target_face", i) for i in range(len(target_boxes))),
419
+ target_boxes,
420
+ )
421
+ scene_min = np.min(target, axis=0)
422
+ scene_max = np.max(target, axis=0)
423
+ scene_corners = np.asarray([
424
+ (x, y, z) for x in (scene_min[0], scene_max[0])
425
+ for y in (scene_min[1], scene_max[1])
426
+ for z in (scene_min[2], scene_max[2])
427
+ ])
428
+ scale = max(1.0, float(np.max(np.abs(source))),
429
+ float(np.max(np.abs(target))))
430
+ margin = 256.0*np.finfo(float).eps*scale
431
+ candidate_indices: set[int] = set()
432
+ for source_index, nodes in enumerate(self.source_face_indices):
433
+ positions = source[nodes]
434
+ if len(nodes) == 4:
435
+ face, normal = projected_q4_source_face(positions)
436
+ else:
437
+ face = PlanarFace((1, source_index+1), positions)
438
+ normal = np.cross(positions[1]-positions[0],
439
+ positions[2]-positions[0])
440
+ normal /= np.linalg.norm(normal)
441
+ tangent = face.corners[1]-face.corners[0]
442
+ tangent /= np.linalg.norm(tangent)
443
+ binormal = np.cross(normal, tangent)
444
+ origin = face.corners[0]
445
+ source_relative = face.corners-origin
446
+ source_xy = np.column_stack((source_relative@tangent,
447
+ source_relative@binormal))
448
+ low = np.min(source_xy, axis=0)-margin
449
+ high = np.max(source_xy, axis=0)+margin
450
+ depth = (scene_corners-origin)@normal
451
+ prism = np.asarray([
452
+ origin+a*tangent+b*binormal+c*normal
453
+ for a in (low[0], high[0])
454
+ for b in (low[1], high[1])
455
+ for c in (np.min(depth)-margin, np.max(depth)+margin)
456
+ ])
457
+ box = np.r_[np.min(prism, axis=0), np.max(prism, axis=0)]
458
+ candidate_indices.update(
459
+ source_index*len(self.target_faces)+key[1]
460
+ for key in search.query(box, padding=4*margin)
461
+ )
462
+ return candidate_indices
463
+
464
+ def work(self, current_source: np.ndarray, current_target: np.ndarray,
465
+ *, tangent: bool = True) -> MovingS3PatchMortarWork:
466
+ if self.differentiation != "global":
467
+ raise ValueError("pair-local geometry requires projected normal work")
468
+ coordinates = np.concatenate((np.asarray(current_source, dtype=float),
469
+ np.asarray(current_target, dtype=float))).reshape(-1)
470
+ if coordinates.size != self.n_coordinates:
471
+ raise ValueError("S3 patch work has invalid physical coordinate count")
472
+ source_count = 3*len(self.source_node_ids)
473
+ def state_at(values):
474
+ return self.evaluate(values[:source_count].reshape(-1, 3),
475
+ values[source_count:].reshape(-1, 3))
476
+ base = state_at(coordinates)
477
+ if base.energy == 0.0:
478
+ return MovingS3PatchMortarWork(
479
+ base, np.zeros(self.n_coordinates),
480
+ np.zeros((self.n_coordinates, self.n_coordinates)) if tangent else None,
481
+ 1,
482
+ )
483
+ for index, law in enumerate(self.pair_laws):
484
+ source_face = index // len(self.target_faces)
485
+ target_face = index % len(self.target_faces)
486
+ source_positions = np.asarray(current_source)[self.source_face_indices[source_face]]
487
+ target_positions = np.asarray(current_target)[self.target_face_indices[target_face]]
488
+ if len(source_positions) == 4:
489
+ first, normal = projected_q4_source_face(source_positions)
490
+ else:
491
+ first = PlanarFace((1, 1), source_positions)
492
+ normal = np.cross(first.corners[1]-first.corners[0],
493
+ first.corners[2]-first.corners[0])
494
+ normal /= np.linalg.norm(normal)
495
+ projected_target = target_positions - (
496
+ (target_positions-first.corners[0])@normal
497
+ )[:, None]*normal
498
+ second = PlanarFace((2, 1), projected_target)
499
+ overlap = planar_projected_overlap(first, second)
500
+ if (overlap is not None
501
+ and _has_shared_edge_transition(first, second, overlap)):
502
+ raise ValueError("S3 patch shared-edge derivative is nonunique")
503
+ evaluations = 1
504
+ cache: dict[tuple[tuple[int, int], ...], float] = {}
505
+ def energy_at(steps):
506
+ nonlocal evaluations
507
+ key = tuple(sorted(steps))
508
+ if key in cache:
509
+ return cache[key]
510
+ evaluations += 1
511
+ if evaluations > self.maximum_energy_evaluations:
512
+ raise MemoryError("S3 patch differentiation budget exhausted")
513
+ trial = coordinates.copy()
514
+ for coordinate, sign in steps:
515
+ trial[coordinate] += sign*self.difference_step
516
+ result = state_at(trial)
517
+ # Internal clipping diagonals can switch polygon combinatorics while
518
+ # the shared-node patch potential remains smooth. Differentiate the
519
+ # aggregate energy; same-side overlap and true shared-edge contacts
520
+ # are checked independently above.
521
+ cache[key] = result.energy
522
+ return result.energy
523
+ positive = np.empty(self.n_coordinates)
524
+ negative = np.empty(self.n_coordinates)
525
+ residual = np.empty(self.n_coordinates)
526
+ for coordinate in range(self.n_coordinates):
527
+ positive[coordinate] = energy_at(((coordinate, 1),))
528
+ negative[coordinate] = energy_at(((coordinate, -1),))
529
+ residual[coordinate] = ((positive[coordinate]-negative[coordinate])
530
+ /(2.0*self.difference_step))
531
+ hessian = None
532
+ if tangent:
533
+ hessian = np.empty((self.n_coordinates, self.n_coordinates))
534
+ for first in range(self.n_coordinates):
535
+ hessian[first, first] = (
536
+ positive[first]-2.0*base.energy+negative[first]
537
+ )/self.difference_step**2
538
+ for second in range(first+1, self.n_coordinates):
539
+ hessian[first, second] = hessian[second, first] = (
540
+ energy_at(((first, 1), (second, 1)))
541
+ - energy_at(((first, 1), (second, -1)))
542
+ - energy_at(((first, -1), (second, 1)))
543
+ + energy_at(((first, -1), (second, -1)))
544
+ )/(4.0*self.difference_step**2)
545
+ return MovingS3PatchMortarWork(base, residual, hessian, evaluations)