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.
- anyfesolver/__init__.py +1075 -0
- anyfesolver/_b2_attachment_elimination_dev.py +261 -0
- anyfesolver/_b2_f10_f11_point_attachment.py +163 -0
- anyfesolver/_b2_loaded_point_trace_dev.py +173 -0
- anyfesolver/_b2_physical_flexibility_linear.py +707 -0
- anyfesolver/_b2_physical_linear_batch_dev.py +491 -0
- anyfesolver/_b2_physical_linear_definition.py +415 -0
- anyfesolver/_b2_physical_load_bubbles.py +282 -0
- anyfesolver/_compensated_contractions.py +497 -0
- anyfesolver/_compensated_native.py +437 -0
- anyfesolver/_corotational_batch.py +219 -0
- anyfesolver/_director_trace.py +214 -0
- anyfesolver/_dyadic_bilinear.py +76 -0
- anyfesolver/_dyadic_factor_chain.py +25 -0
- anyfesolver/_ge_beam3_adaptive_arc_program.py +286 -0
- anyfesolver/_ge_beam3_analysis_combined.py +102 -0
- anyfesolver/_ge_beam3_analysis_fibre_translation.py +130 -0
- anyfesolver/_ge_beam3_analysis_modal_snapshot.py +27 -0
- anyfesolver/_ge_beam3_analysis_nodal_program.py +140 -0
- anyfesolver/_ge_beam3_analysis_translation.py +147 -0
- anyfesolver/_ge_beam3_analysis_translation_modal.py +84 -0
- anyfesolver/_ge_beam3_arc_geometry.py +89 -0
- anyfesolver/_ge_beam3_arc_program.py +304 -0
- anyfesolver/_ge_beam3_authoritative_cell_seed.py +25 -0
- anyfesolver/_ge_beam3_cell_identity.py +52 -0
- anyfesolver/_ge_beam3_centered_batched_finite_inertia.py +132 -0
- anyfesolver/_ge_beam3_centered_finite_inertia.py +171 -0
- anyfesolver/_ge_beam3_centered_mixed.py +104 -0
- anyfesolver/_ge_beam3_centered_reference.py +187 -0
- anyfesolver/_ge_beam3_centered_so3_strain.py +76 -0
- anyfesolver/_ge_beam3_complementary_section.py +122 -0
- anyfesolver/_ge_beam3_compliance_snapshot_guard.py +20 -0
- anyfesolver/_ge_beam3_connected_dynamic.py +486 -0
- anyfesolver/_ge_beam3_connected_trajectory.py +258 -0
- anyfesolver/_ge_beam3_conservative_backtrack.py +26 -0
- anyfesolver/_ge_beam3_controlled_fibre_modes.py +105 -0
- anyfesolver/_ge_beam3_coupled_beam_subdomain.py +128 -0
- anyfesolver/_ge_beam3_coupled_modes.py +256 -0
- anyfesolver/_ge_beam3_deterministic_reduction.py +264 -0
- anyfesolver/_ge_beam3_displacement_program.py +255 -0
- anyfesolver/_ge_beam3_durable_coupled.py +251 -0
- anyfesolver/_ge_beam3_dynamic_elastic_state.py +461 -0
- anyfesolver/_ge_beam3_effective_deadline.py +58 -0
- anyfesolver/_ge_beam3_elastic_seed_continuation.py +223 -0
- anyfesolver/_ge_beam3_elastic_seed_modal.py +139 -0
- anyfesolver/_ge_beam3_equilibrium_line_program.py +98 -0
- anyfesolver/_ge_beam3_equilibrium_schur_solver.py +96 -0
- anyfesolver/_ge_beam3_factor_chain_modes.py +103 -0
- anyfesolver/_ge_beam3_fibre_cell.py +408 -0
- anyfesolver/_ge_beam3_fibre_distributed_couples.py +191 -0
- anyfesolver/_ge_beam3_fibre_kinematic_cell.py +75 -0
- anyfesolver/_ge_beam3_fibre_line_program.py +157 -0
- anyfesolver/_ge_beam3_fibre_line_work.py +87 -0
- anyfesolver/_ge_beam3_fibre_reference_modal.py +104 -0
- anyfesolver/_ge_beam3_fibre_schur_solver.py +134 -0
- anyfesolver/_ge_beam3_fibre_section.py +286 -0
- anyfesolver/_ge_beam3_fibre_static_boundary.py +113 -0
- anyfesolver/_ge_beam3_g1_analysis.py +307 -0
- anyfesolver/_ge_beam3_g1_elastic.py +161 -0
- anyfesolver/_ge_beam3_g1_element.py +185 -0
- anyfesolver/_ge_beam3_g1_operator.py +137 -0
- anyfesolver/_ge_beam3_g2_analysis.py +176 -0
- anyfesolver/_ge_beam3_g2_constraints.py +162 -0
- anyfesolver/_ge_beam3_g3_analysis.py +385 -0
- anyfesolver/_ge_beam3_g3_constraints.py +168 -0
- anyfesolver/_ge_beam3_g3b_owner.py +296 -0
- anyfesolver/_ge_beam3_g3b_q4_reference.py +186 -0
- anyfesolver/_ge_beam3_g3b_reference.py +206 -0
- anyfesolver/_ge_beam3_g3b_result_schema.py +107 -0
- anyfesolver/_ge_beam3_g3b_s3_reference.py +185 -0
- anyfesolver/_ge_beam3_g3b_weighted_reference.py +193 -0
- anyfesolver/_ge_beam3_g3c_affine_q4_chart.py +58 -0
- anyfesolver/_ge_beam3_g3c_affine_q4_increment_chart.py +257 -0
- anyfesolver/_ge_beam3_g3c_affine_q4_recovery.py +434 -0
- anyfesolver/_ge_beam3_g3c_affine_q4_registry.py +127 -0
- anyfesolver/_ge_beam3_g3c_b2_physical.py +153 -0
- anyfesolver/_ge_beam3_g3c_b2_physical_adapter.py +160 -0
- anyfesolver/_ge_beam3_g3c_definition.py +117 -0
- anyfesolver/_ge_beam3_g3c_local_beam.py +188 -0
- anyfesolver/_ge_beam3_g3c_local_shell.py +371 -0
- anyfesolver/_ge_beam3_g3c_owner.py +400 -0
- anyfesolver/_ge_beam3_g3c_physical_authority.py +203 -0
- anyfesolver/_ge_beam3_g3c_physical_owner.py +556 -0
- anyfesolver/_ge_beam3_g3c_recovery.py +91 -0
- anyfesolver/_ge_beam3_g3c_so3_numerics.py +81 -0
- anyfesolver/_ge_beam3_g3c_stable/__init__.py +1 -0
- anyfesolver/_ge_beam3_g3c_stable/authority.py +152 -0
- anyfesolver/_ge_beam3_g3c_stable/beam.py +196 -0
- anyfesolver/_ge_beam3_g3c_stable/boundary.py +38 -0
- anyfesolver/_ge_beam3_g3c_stable/chart.py +23 -0
- anyfesolver/_ge_beam3_g3c_stable/compensated.py +46 -0
- anyfesolver/_ge_beam3_g3c_stable/element.py +190 -0
- anyfesolver/_ge_beam3_g3c_stable/fit.py +54 -0
- anyfesolver/_ge_beam3_g3c_stable/joint.py +255 -0
- anyfesolver/_ge_beam3_g3c_stable/line_work.py +92 -0
- anyfesolver/_ge_beam3_g3c_stable/operator.py +147 -0
- anyfesolver/_ge_beam3_g3c_stable/owner.py +415 -0
- anyfesolver/_ge_beam3_g3c_stable/shell.py +358 -0
- anyfesolver/_ge_beam3_g4_completion.py +186 -0
- anyfesolver/_ge_beam3_g4a_station_transaction.py +385 -0
- anyfesolver/_ge_beam3_g5_completion.py +68 -0
- anyfesolver/_ge_beam3_g6_domain.py +354 -0
- anyfesolver/_ge_beam3_generalized_cell.py +172 -0
- anyfesolver/_ge_beam3_generalized_ellipsoid_section.py +215 -0
- anyfesolver/_ge_beam3_generalized_static_boundary.py +233 -0
- anyfesolver/_ge_beam3_lifted_kinetic_factor.py +26 -0
- anyfesolver/_ge_beam3_line_fibre_modes.py +121 -0
- anyfesolver/_ge_beam3_load_program.py +275 -0
- anyfesolver/_ge_beam3_loaded_modal.py +225 -0
- anyfesolver/_ge_beam3_mixed_ad.py +286 -0
- anyfesolver/_ge_beam3_native_analysis.py +484 -0
- anyfesolver/_ge_beam3_native_arc.py +269 -0
- anyfesolver/_ge_beam3_native_arc_adaptive.py +251 -0
- anyfesolver/_ge_beam3_native_arc_restart.py +88 -0
- anyfesolver/_ge_beam3_native_arc_source.py +62 -0
- anyfesolver/_ge_beam3_native_buckling.py +206 -0
- anyfesolver/_ge_beam3_native_combined_couples.py +179 -0
- anyfesolver/_ge_beam3_native_combined_restart.py +205 -0
- anyfesolver/_ge_beam3_native_definition.py +238 -0
- anyfesolver/_ge_beam3_native_distributed_element.py +220 -0
- anyfesolver/_ge_beam3_native_distributed_loading.py +92 -0
- anyfesolver/_ge_beam3_native_distributed_program.py +165 -0
- anyfesolver/_ge_beam3_native_distributed_recovery.py +34 -0
- anyfesolver/_ge_beam3_native_distributed_restart.py +221 -0
- anyfesolver/_ge_beam3_native_dynamic_analysis.py +149 -0
- anyfesolver/_ge_beam3_native_dynamic_restart.py +261 -0
- anyfesolver/_ge_beam3_native_fibre_current_modal.py +104 -0
- anyfesolver/_ge_beam3_native_fibre_recovery.py +34 -0
- anyfesolver/_ge_beam3_native_fibre_restart.py +211 -0
- anyfesolver/_ge_beam3_native_fibre_static_element.py +193 -0
- anyfesolver/_ge_beam3_native_force_adaptation.py +56 -0
- anyfesolver/_ge_beam3_native_generalized_combined_couples.py +188 -0
- anyfesolver/_ge_beam3_native_generalized_combined_restart.py +207 -0
- anyfesolver/_ge_beam3_native_generalized_element.py +222 -0
- anyfesolver/_ge_beam3_native_generalized_factor_modal.py +122 -0
- anyfesolver/_ge_beam3_native_generalized_loading.py +92 -0
- anyfesolver/_ge_beam3_native_generalized_modal.py +274 -0
- anyfesolver/_ge_beam3_native_generalized_paired_modal.py +13 -0
- anyfesolver/_ge_beam3_native_generalized_parameter.py +89 -0
- anyfesolver/_ge_beam3_native_generalized_program.py +196 -0
- anyfesolver/_ge_beam3_native_generalized_recovery.py +34 -0
- anyfesolver/_ge_beam3_native_generalized_restart.py +243 -0
- anyfesolver/_ge_beam3_native_history_profile.py +53 -0
- anyfesolver/_ge_beam3_native_line_loading.py +93 -0
- anyfesolver/_ge_beam3_native_line_program.py +150 -0
- anyfesolver/_ge_beam3_native_line_recovery.py +34 -0
- anyfesolver/_ge_beam3_native_line_restart.py +197 -0
- anyfesolver/_ge_beam3_native_line_static_element.py +220 -0
- anyfesolver/_ge_beam3_native_load_admission.py +37 -0
- anyfesolver/_ge_beam3_native_midpoint.py +1004 -0
- anyfesolver/_ge_beam3_native_multi_shell_contact.py +539 -0
- anyfesolver/_ge_beam3_native_pair_contact.py +236 -0
- anyfesolver/_ge_beam3_native_shell_contact.py +357 -0
- anyfesolver/_ge_beam3_native_spatial_couples.py +176 -0
- anyfesolver/_ge_beam3_native_spatial_restart.py +204 -0
- anyfesolver/_ge_beam3_native_transient.py +467 -0
- anyfesolver/_ge_beam3_native_translation.py +225 -0
- anyfesolver/_ge_beam3_native_translation_restart.py +54 -0
- anyfesolver/_ge_beam3_operator_validation_scope.py +53 -0
- anyfesolver/_ge_beam3_p5/__init__.py +11 -0
- anyfesolver/_ge_beam3_p5/algebra.py +91 -0
- anyfesolver/_ge_beam3_p5/arrays.py +29 -0
- anyfesolver/_ge_beam3_p5/chart.py +45 -0
- anyfesolver/_ge_beam3_p5/codec.py +82 -0
- anyfesolver/_ge_beam3_p5/committed_modal.py +191 -0
- anyfesolver/_ge_beam3_p5/compensated.py +118 -0
- anyfesolver/_ge_beam3_p5/compensated_coordinates.py +44 -0
- anyfesolver/_ge_beam3_p5/core.py +159 -0
- anyfesolver/_ge_beam3_p5/element.py +207 -0
- anyfesolver/_ge_beam3_p5/factors.py +61 -0
- anyfesolver/_ge_beam3_p5/inertia.py +120 -0
- anyfesolver/_ge_beam3_p5/mass.py +70 -0
- anyfesolver/_ge_beam3_p5/mixed.py +256 -0
- anyfesolver/_ge_beam3_p5/reference_modal.py +73 -0
- anyfesolver/_ge_beam3_p5/section.py +139 -0
- anyfesolver/_ge_beam3_p5/typed_schema.py +111 -0
- anyfesolver/_ge_beam3_p5_centered/__init__.py +6 -0
- anyfesolver/_ge_beam3_p5_centered/codec.py +84 -0
- anyfesolver/_ge_beam3_p5_centered/committed_modal.py +192 -0
- anyfesolver/_ge_beam3_p5_centered/core.py +171 -0
- anyfesolver/_ge_beam3_p5_centered/element.py +216 -0
- anyfesolver/_ge_beam3_p5_centered/mass.py +99 -0
- anyfesolver/_ge_beam3_p5_centered/positions.py +34 -0
- anyfesolver/_ge_beam3_p5_centered/reference_modal.py +73 -0
- anyfesolver/_ge_beam3_p5_coordinates/__init__.py +6 -0
- anyfesolver/_ge_beam3_p5_coordinates/codec.py +84 -0
- anyfesolver/_ge_beam3_p5_coordinates/committed_modal.py +192 -0
- anyfesolver/_ge_beam3_p5_coordinates/core.py +163 -0
- anyfesolver/_ge_beam3_p5_coordinates/element.py +213 -0
- anyfesolver/_ge_beam3_p5_coordinates/positions.py +102 -0
- anyfesolver/_ge_beam3_p5_coordinates/reference_modal.py +73 -0
- anyfesolver/_ge_beam3_p5_loads/__init__.py +7 -0
- anyfesolver/_ge_beam3_p5_loads/codec.py +85 -0
- anyfesolver/_ge_beam3_p5_loads/core.py +192 -0
- anyfesolver/_ge_beam3_p5_loads/element.py +243 -0
- anyfesolver/_ge_beam3_p5_loads/state.py +120 -0
- anyfesolver/_ge_beam3_p5_loads/work.py +45 -0
- anyfesolver/_ge_beam3_p5_seeded/__init__.py +9 -0
- anyfesolver/_ge_beam3_p5_seeded/codec.py +87 -0
- anyfesolver/_ge_beam3_p5_seeded/core.py +197 -0
- anyfesolver/_ge_beam3_p5_seeded/element.py +245 -0
- anyfesolver/_ge_beam3_p5_seeded/state.py +122 -0
- anyfesolver/_ge_beam3_p5_seeded/work.py +47 -0
- anyfesolver/_ge_beam3_pose_joint.py +268 -0
- anyfesolver/_ge_beam3_precise_geometric_work.py +147 -0
- anyfesolver/_ge_beam3_reassembled_signed_modes.py +101 -0
- anyfesolver/_ge_beam3_reference_identity.py +92 -0
- anyfesolver/_ge_beam3_refined_fibre_schur_solver.py +104 -0
- anyfesolver/_ge_beam3_refinement_capacity.py +19 -0
- anyfesolver/_ge_beam3_relative_virgin_reference_modes.py +60 -0
- anyfesolver/_ge_beam3_retained_arc.py +350 -0
- anyfesolver/_ge_beam3_retained_arc_geometry.py +66 -0
- anyfesolver/_ge_beam3_retained_arc_modal.py +125 -0
- anyfesolver/_ge_beam3_retained_elastic.py +134 -0
- anyfesolver/_ge_beam3_retained_fibre.py +209 -0
- anyfesolver/_ge_beam3_retained_fibre_control.py +270 -0
- anyfesolver/_ge_beam3_retained_fibre_element.py +58 -0
- anyfesolver/_ge_beam3_retained_fibre_modal.py +155 -0
- anyfesolver/_ge_beam3_retained_fibre_modes.py +189 -0
- anyfesolver/_ge_beam3_retained_fibre_program.py +68 -0
- anyfesolver/_ge_beam3_retained_fibre_state.py +268 -0
- anyfesolver/_ge_beam3_retained_force_program.py +72 -0
- anyfesolver/_ge_beam3_retained_generalized.py +186 -0
- anyfesolver/_ge_beam3_retained_generalized_modal.py +171 -0
- anyfesolver/_ge_beam3_retained_generalized_program.py +63 -0
- anyfesolver/_ge_beam3_retained_generalized_state.py +281 -0
- anyfesolver/_ge_beam3_retained_nodal_loading.py +111 -0
- anyfesolver/_ge_beam3_retained_plastic.py +116 -0
- anyfesolver/_ge_beam3_retained_plastic_modes.py +144 -0
- anyfesolver/_ge_beam3_retained_plastic_program.py +69 -0
- anyfesolver/_ge_beam3_retained_plastic_state.py +165 -0
- anyfesolver/_ge_beam3_retained_state.py +194 -0
- anyfesolver/_ge_beam3_retained_translation_control.py +345 -0
- anyfesolver/_ge_beam3_retained_translation_modal.py +137 -0
- anyfesolver/_ge_beam3_schur_line_program.py +98 -0
- anyfesolver/_ge_beam3_seeded_fibre_control.py +175 -0
- anyfesolver/_ge_beam3_seeded_load_program.py +301 -0
- anyfesolver/_ge_beam3_seeded_loaded_modal.py +226 -0
- anyfesolver/_ge_beam3_seeded_signed_modes.py +150 -0
- anyfesolver/_ge_beam3_shared_kinematic_split.py +53 -0
- anyfesolver/_ge_beam3_shell_joint_state.py +396 -0
- anyfesolver/_ge_beam3_shell_joint_trial.py +217 -0
- anyfesolver/_ge_beam3_signed_loaded_modes.py +140 -0
- anyfesolver/_ge_beam3_spatial_fibre_program.py +113 -0
- anyfesolver/_ge_beam3_spatial_nodal_moments.py +38 -0
- anyfesolver/_ge_beam3_station_resultant_cell.py +235 -0
- anyfesolver/_ge_beam3_variational_shell.py +211 -0
- anyfesolver/_ge_beam3_virgin_reference_modes.py +60 -0
- anyfesolver/_impact_coupling.py +162 -0
- anyfesolver/_native_authority_dag.py +77 -0
- anyfesolver/_native_dyadic_interval_inertia.py +64 -0
- anyfesolver/_native_exact_shift_chain_modes.py +140 -0
- anyfesolver/_native_exact_shift_inertia.py +86 -0
- anyfesolver/_native_factor_chain_modes.py +192 -0
- anyfesolver/_native_guard.cpp +828 -0
- anyfesolver/_native_guard_dispatch.py +140 -0
- anyfesolver/_native_large_factor_chain.py +55 -0
- anyfesolver/_native_material_protocol.py +51 -0
- anyfesolver/_native_midpoint_controller.py +90 -0
- anyfesolver/_native_modal_capacity.py +26 -0
- anyfesolver/_native_paired_factor_chain_modes.py +244 -0
- anyfesolver/_native_reassembled_factor_modes.py +185 -0
- anyfesolver/_native_reference_factor_spectrum.py +102 -0
- anyfesolver/_native_reference_modal.py +180 -0
- anyfesolver/_native_relative_factor_chain_modes.py +204 -0
- anyfesolver/_native_relative_reference_factor_spectrum.py +110 -0
- anyfesolver/_native_retained_step.py +15 -0
- anyfesolver/_native_rotation_state.py +797 -0
- anyfesolver/_native_signed_factor_modes.py +257 -0
- anyfesolver/_native_signed_kinetic_factor_modes.py +279 -0
- anyfesolver/_native_stationary_spectrum.py +79 -0
- anyfesolver/_nonlinear_events.py +150 -0
- anyfesolver/_nonlinear_seed.py +80 -0
- anyfesolver/_paired_modal_arithmetic.py +71 -0
- anyfesolver/_plate_stability_continuation.py +171 -0
- anyfesolver/_q4_assumed_strain_plasticity.py +502 -0
- anyfesolver/_qualified_authority_epoch.py +561 -0
- anyfesolver/_relative_reference_svd.py +44 -0
- anyfesolver/_stiffened_shell_affine_endpoint.py +232 -0
- anyfesolver/_stiffened_shell_algorithmic_pullback.py +38 -0
- anyfesolver/_stiffened_shell_arc_checkpoint.py +422 -0
- anyfesolver/_stiffened_shell_arc_control.py +108 -0
- anyfesolver/_stiffened_shell_arc_metric.py +222 -0
- anyfesolver/_stiffened_shell_arc_publication.py +153 -0
- anyfesolver/_stiffened_shell_arc_trial.py +310 -0
- anyfesolver/_stiffened_shell_b2_affine_resolution.py +101 -0
- anyfesolver/_stiffened_shell_b2_assembly_diagnostics.py +172 -0
- anyfesolver/_stiffened_shell_b2_definition_ownership.py +189 -0
- anyfesolver/_stiffened_shell_b2_experimental.py +153 -0
- anyfesolver/_stiffened_shell_b2_nodal_footprint.py +273 -0
- anyfesolver/_stiffened_shell_b2_physical_rigid_footprint.py +237 -0
- anyfesolver/_stiffened_shell_b2_q4_panel_experimental.py +2447 -0
- anyfesolver/_stiffened_shell_b2_q4_point_experimental.py +251 -0
- anyfesolver/_stiffened_shell_b2_reference_buckling.py +413 -0
- anyfesolver/_stiffened_shell_b3_chart.py +70 -0
- anyfesolver/_stiffened_shell_b3_local_adapter.py +141 -0
- anyfesolver/_stiffened_shell_beam_history.py +107 -0
- anyfesolver/_stiffened_shell_bl5_local_experimental.py +173 -0
- anyfesolver/_stiffened_shell_bl5_native_elastic.py +28 -0
- anyfesolver/_stiffened_shell_branch_event_trial.py +58 -0
- anyfesolver/_stiffened_shell_consumer_capabilities.py +124 -0
- anyfesolver/_stiffened_shell_coordinate_support.py +110 -0
- anyfesolver/_stiffened_shell_displacement_adaptive.py +327 -0
- anyfesolver/_stiffened_shell_displacement_checkpoint.py +360 -0
- anyfesolver/_stiffened_shell_displacement_control.py +326 -0
- anyfesolver/_stiffened_shell_displacement_corrector.py +293 -0
- anyfesolver/_stiffened_shell_displacement_increment.py +121 -0
- anyfesolver/_stiffened_shell_distributing_footprint.py +354 -0
- anyfesolver/_stiffened_shell_distributing_pose.py +267 -0
- anyfesolver/_stiffened_shell_f06_increment_arithmetic.py +205 -0
- anyfesolver/_stiffened_shell_ge_body_load.py +300 -0
- anyfesolver/_stiffened_shell_ge_checkpoint_binary.py +472 -0
- anyfesolver/_stiffened_shell_ge_distributed_load.py +210 -0
- anyfesolver/_stiffened_shell_ge_distributed_programme.py +175 -0
- anyfesolver/_stiffened_shell_ge_distributing_finite.py +242 -0
- anyfesolver/_stiffened_shell_ge_distributing_reference.py +296 -0
- anyfesolver/_stiffened_shell_ge_experimental.py +2454 -0
- anyfesolver/_stiffened_shell_ge_finite_experimental.py +2714 -0
- anyfesolver/_stiffened_shell_ge_mixed_modal_mass.py +33 -0
- anyfesolver/_stiffened_shell_ge_point_buckling.py +723 -0
- anyfesolver/_stiffened_shell_ge_pressure_load.py +366 -0
- anyfesolver/_stiffened_shell_ge_reference_modal.py +580 -0
- anyfesolver/_stiffened_shell_generalized_recovery.py +150 -0
- anyfesolver/_stiffened_shell_increment_control.py +217 -0
- anyfesolver/_stiffened_shell_l1_assembly_experimental.py +420 -0
- anyfesolver/_stiffened_shell_l1_local_experimental.py +284 -0
- anyfesolver/_stiffened_shell_l1_supported_work_experimental.py +146 -0
- anyfesolver/_stiffened_shell_native_distributed_load.py +120 -0
- anyfesolver/_stiffened_shell_native_gravity.py +236 -0
- anyfesolver/_stiffened_shell_nodal_footprint.py +255 -0
- anyfesolver/_stiffened_shell_physical_q4_mass.py +98 -0
- anyfesolver/_stiffened_shell_physical_s3_mass.py +53 -0
- anyfesolver/_stiffened_shell_point_recovery.py +49 -0
- anyfesolver/_stiffened_shell_q4_algorithmic_pullback.py +88 -0
- anyfesolver/_stiffened_shell_q4_material_event.py +114 -0
- anyfesolver/_stiffened_shell_q4_reference.py +65 -0
- anyfesolver/_stiffened_shell_rotation_charts.py +58 -0
- anyfesolver/_stiffened_shell_s3_algorithmic_pullback.py +59 -0
- anyfesolver/_stiffened_shell_s3_conservative_buckling.py +28 -0
- anyfesolver/_stiffened_shell_s3_dead_work_candidate.py +107 -0
- anyfesolver/_stiffened_shell_s3_material_event.py +30 -0
- anyfesolver/_stiffened_shell_same_parent_trial.py +224 -0
- anyfesolver/_stiffened_shell_selected_recovery.py +113 -0
- anyfesolver/_stiffened_shell_staged_load_experimental.py +392 -0
- anyfesolver/_stiffened_shell_stress_free_reference.py +204 -0
- anyfesolver/_wire_types.py +17 -0
- anyfesolver/activity.py +1537 -0
- anyfesolver/algebraic_dynamics.py +2864 -0
- anyfesolver/analysis_session.py +897 -0
- anyfesolver/anystructure_fem_mode.py +1637 -0
- anyfesolver/arc_length.py +2587 -0
- anyfesolver/assembly.py +1830 -0
- anyfesolver/b3_ge.py +179 -0
- anyfesolver/baselines.py +303 -0
- anyfesolver/beam_sections.py +292 -0
- anyfesolver/beam_shell_verification.py +4685 -0
- anyfesolver/beam_validity.py +110 -0
- anyfesolver/benchmarks.py +495 -0
- anyfesolver/boundary.py +1680 -0
- anyfesolver/buckling.py +2136 -0
- anyfesolver/buckling_validity.py +91 -0
- anyfesolver/capacity_workflow.py +431 -0
- anyfesolver/capsule_runtime_guard.py +99 -0
- anyfesolver/cases.py +173 -0
- anyfesolver/composite_strip_verification.py +297 -0
- anyfesolver/concentrated_mass.py +84 -0
- anyfesolver/constraint_audit.py +553 -0
- anyfesolver/contact.py +4785 -0
- anyfesolver/contact_performance.py +301 -0
- anyfesolver/control.py +206 -0
- anyfesolver/corotational.py +1935 -0
- anyfesolver/corotational_performance.py +157 -0
- anyfesolver/current_state_tangent.py +2780 -0
- anyfesolver/cylinder_benchmarks.py +369 -0
- anyfesolver/damage_matrix_performance.py +617 -0
- anyfesolver/dynamics.py +2833 -0
- anyfesolver/e4_pl_element.py +8265 -0
- anyfesolver/e4_pl_enriched.py +194 -0
- anyfesolver/e4_pl_enriched_nonlinear.py +159 -0
- anyfesolver/e4_pl_s3_element.py +9752 -0
- anyfesolver/e4_pl_s3_initial_fields.py +101 -0
- anyfesolver/e4_pl_s3_state.py +4723 -0
- anyfesolver/e4_pl_s3_v2_element.py +1844 -0
- anyfesolver/e4_pl_s3_v2b_element.py +1936 -0
- anyfesolver/e4_pl_s3_v2c_element.py +2196 -0
- anyfesolver/e4_pl_s3_v2d_element.py +2621 -0
- anyfesolver/e4_pl_s3_v2d_state.py +376 -0
- anyfesolver/element_capabilities.py +159 -0
- anyfesolver/element_qualification.py +432 -0
- anyfesolver/elements.py +6327 -0
- anyfesolver/experimental_csr_assembly.py +238 -0
- anyfesolver/external_references.py +1253 -0
- anyfesolver/fe_core.py +832 -0
- anyfesolver/floating_pressure_regions.py +119 -0
- anyfesolver/floating_response.py +486 -0
- anyfesolver/floating_transient.py +1281 -0
- anyfesolver/fracture.py +621 -0
- anyfesolver/ge_beam3_curved_reference.py +725 -0
- anyfesolver/ge_beam3_element.py +885 -0
- anyfesolver/ge_beam3_mixed_element.py +1216 -0
- anyfesolver/ge_beam3_mixed_state.py +814 -0
- anyfesolver/ge_beam3_native.py +129 -0
- anyfesolver/ge_beam3_native_connected_dynamics.py +24 -0
- anyfesolver/ge_beam3_native_dynamics.py +70 -0
- anyfesolver/ge_beam3_state.py +672 -0
- anyfesolver/general_contact/__init__.py +151 -0
- anyfesolver/general_contact/_enriched_multitarget_empty.py +202 -0
- anyfesolver/general_contact/_enriched_multitarget_trial.py +183 -0
- anyfesolver/general_contact/_results_archive_common.py +65 -0
- anyfesolver/general_contact/algebraic_path.py +206 -0
- anyfesolver/general_contact/arc_contact.py +237 -0
- anyfesolver/general_contact/arc_results_archive.py +158 -0
- anyfesolver/general_contact/augmentation.py +157 -0
- anyfesolver/general_contact/automatic_domain.py +621 -0
- anyfesolver/general_contact/beam_chain_consistent.py +357 -0
- anyfesolver/general_contact/beam_chain_end_geometry.py +237 -0
- anyfesolver/general_contact/beam_chain_ends.py +220 -0
- anyfesolver/general_contact/beam_chain_pair.py +416 -0
- anyfesolver/general_contact/beam_curve_end_geometry.py +254 -0
- anyfesolver/general_contact/beam_curve_ends.py +237 -0
- anyfesolver/general_contact/beam_curve_pair.py +794 -0
- anyfesolver/general_contact/beam_curve_pair_static.py +303 -0
- anyfesolver/general_contact/beam_end_radial_geometry.py +221 -0
- anyfesolver/general_contact/beam_end_topology.py +15 -0
- anyfesolver/general_contact/beam_hemisphere_coupled_tool.py +61 -0
- anyfesolver/general_contact/beam_hemisphere_cylinder.py +134 -0
- anyfesolver/general_contact/beam_hemisphere_cylinder_motion.py +89 -0
- anyfesolver/general_contact/beam_hemisphere_cylinder_work.py +216 -0
- anyfesolver/general_contact/beam_hemisphere_plane.py +175 -0
- anyfesolver/general_contact/beam_hemisphere_s3_support.py +152 -0
- anyfesolver/general_contact/beam_hemisphere_sphere.py +135 -0
- anyfesolver/general_contact/beam_hemisphere_sphere_work.py +114 -0
- anyfesolver/general_contact/beam_hemisphere_support.py +211 -0
- anyfesolver/general_contact/beam_pair.py +523 -0
- anyfesolver/general_contact/beam_pair_end_geometry.py +269 -0
- anyfesolver/general_contact/beam_pair_ends.py +222 -0
- anyfesolver/general_contact/beam_plane.py +425 -0
- anyfesolver/general_contact/beam_radial.py +500 -0
- anyfesolver/general_contact/beam_radial_ends.py +223 -0
- anyfesolver/general_contact/beam_s3_directional_rates.py +196 -0
- anyfesolver/general_contact/beam_s3_rotational_transient.py +126 -0
- anyfesolver/general_contact/beam_s3_transient.py +139 -0
- anyfesolver/general_contact/beam_shell.py +648 -0
- anyfesolver/general_contact/beam_shell_patch.py +395 -0
- anyfesolver/general_contact/beam_temporal_bounds.py +230 -0
- anyfesolver/general_contact/capability.py +101 -0
- anyfesolver/general_contact/capped_cylinder.py +618 -0
- anyfesolver/general_contact/contact_search.py +95 -0
- anyfesolver/general_contact/core.py +1769 -0
- anyfesolver/general_contact/curved_s3_q4_work.py +238 -0
- anyfesolver/general_contact/curved_shell_skin.py +520 -0
- anyfesolver/general_contact/d1_interior_profile.py +427 -0
- anyfesolver/general_contact/deformable_beam_s3_caps.py +143 -0
- anyfesolver/general_contact/deformable_beam_s3_line.py +211 -0
- anyfesolver/general_contact/deformable_beam_s3_static.py +152 -0
- anyfesolver/general_contact/descriptor_rates.py +61 -0
- anyfesolver/general_contact/enriched_cold_predictor.py +161 -0
- anyfesolver/general_contact/enriched_moment_batch.py +337 -0
- anyfesolver/general_contact/enriched_multitarget.py +308 -0
- anyfesolver/general_contact/enriched_multitarget_gap.py +156 -0
- anyfesolver/general_contact/enriched_multitarget_moments.py +194 -0
- anyfesolver/general_contact/enriched_multitarget_topology.py +171 -0
- anyfesolver/general_contact/enriched_nonlinear.py +440 -0
- anyfesolver/general_contact/enriched_overlap.py +299 -0
- anyfesolver/general_contact/enriched_path.py +253 -0
- anyfesolver/general_contact/enriched_small_cut.py +310 -0
- anyfesolver/general_contact/enriched_static.py +481 -0
- anyfesolver/general_contact/enriched_union.py +320 -0
- anyfesolver/general_contact/equilibrated_pressure_pivot.py +140 -0
- anyfesolver/general_contact/event_subdivision.py +273 -0
- anyfesolver/general_contact/finite_mixed_state.py +133 -0
- anyfesolver/general_contact/finite_rigid_patch.py +196 -0
- anyfesolver/general_contact/finite_rigid_support.py +129 -0
- anyfesolver/general_contact/finite_rigid_sweep.py +53 -0
- anyfesolver/general_contact/finite_rotation_predictor.py +171 -0
- anyfesolver/general_contact/finite_rotation_skin.py +212 -0
- anyfesolver/general_contact/finite_rotation_state.py +106 -0
- anyfesolver/general_contact/finite_rotation_sweep.py +161 -0
- anyfesolver/general_contact/finite_v2d_state.py +104 -0
- anyfesolver/general_contact/fixed_projection_graph.py +205 -0
- anyfesolver/general_contact/fixed_projection_s3_events.py +235 -0
- anyfesolver/general_contact/free_rigid.py +134 -0
- anyfesolver/general_contact/friction_point.py +378 -0
- anyfesolver/general_contact/gap_extrema.py +119 -0
- anyfesolver/general_contact/guided_pair_transient_geometry.py +138 -0
- anyfesolver/general_contact/initial_contact_seed.py +368 -0
- anyfesolver/general_contact/linearized_pivot.py +595 -0
- anyfesolver/general_contact/material_work_diagnostics.py +159 -0
- anyfesolver/general_contact/moment_batch_ad.py +129 -0
- anyfesolver/general_contact/moment_batch_points.py +75 -0
- anyfesolver/general_contact/moving.py +1031 -0
- anyfesolver/general_contact/multiple_beam_rigid.py +248 -0
- anyfesolver/general_contact/multiple_beam_s3_caps.py +199 -0
- anyfesolver/general_contact/multiple_beam_s3_transient.py +223 -0
- anyfesolver/general_contact/multiple_projected_pairs.py +196 -0
- anyfesolver/general_contact/multiple_shell_planes.py +226 -0
- anyfesolver/general_contact/native_activation_static.py +143 -0
- anyfesolver/general_contact/native_checkpoint_results.py +213 -0
- anyfesolver/general_contact/native_curve_union.py +268 -0
- anyfesolver/general_contact/native_curved_geometry.py +374 -0
- anyfesolver/general_contact/native_curved_pair_partition.py +590 -0
- anyfesolver/general_contact/native_curved_plane_work.py +864 -0
- anyfesolver/general_contact/native_curved_s3_work.py +472 -0
- anyfesolver/general_contact/native_event_polynomial.py +164 -0
- anyfesolver/general_contact/native_fibre_context.py +173 -0
- anyfesolver/general_contact/native_fibre_results.py +74 -0
- anyfesolver/general_contact/native_initial_guess.py +122 -0
- anyfesolver/general_contact/native_material_activation.py +108 -0
- anyfesolver/general_contact/native_material_plane.py +111 -0
- anyfesolver/general_contact/native_material_s3.py +209 -0
- anyfesolver/general_contact/native_multi_s3_static.py +722 -0
- anyfesolver/general_contact/native_normal_angles.py +233 -0
- anyfesolver/general_contact/native_pair_error_budget.py +49 -0
- anyfesolver/general_contact/native_replay_arithmetic.py +103 -0
- anyfesolver/general_contact/native_replay_diagnostics.py +90 -0
- anyfesolver/general_contact/native_retained_body_junction.py +99 -0
- anyfesolver/general_contact/native_retained_body_pair.py +220 -0
- anyfesolver/general_contact/native_retained_body_projection.py +160 -0
- anyfesolver/general_contact/native_retained_body_static.py +62 -0
- anyfesolver/general_contact/native_retained_cell_pair.py +185 -0
- anyfesolver/general_contact/native_retained_curve_cell.py +102 -0
- anyfesolver/general_contact/native_retained_line_plane.py +210 -0
- anyfesolver/general_contact/native_retained_line_s3.py +440 -0
- anyfesolver/general_contact/native_retained_line_s3_work.py +91 -0
- anyfesolver/general_contact/native_retained_pair_static.py +845 -0
- anyfesolver/general_contact/native_retained_s3_static.py +554 -0
- anyfesolver/general_contact/native_retained_static.py +478 -0
- anyfesolver/general_contact/native_retained_station.py +222 -0
- anyfesolver/general_contact/native_retained_whole_pair.py +2120 -0
- anyfesolver/general_contact/native_s3_swept.py +149 -0
- anyfesolver/general_contact/native_shell_static_driver.py +144 -0
- anyfesolver/general_contact/native_surface_activation.py +391 -0
- anyfesolver/general_contact/native_surface_bounds.py +198 -0
- anyfesolver/general_contact/native_surface_contributor.py +121 -0
- anyfesolver/general_contact/native_surface_crossing.py +81 -0
- anyfesolver/general_contact/native_surface_event_sequence.py +320 -0
- anyfesolver/general_contact/native_surface_extrema.py +72 -0
- anyfesolver/general_contact/native_surface_friction_integral.py +1724 -0
- anyfesolver/general_contact/native_surface_front.py +742 -0
- anyfesolver/general_contact/native_surface_front_boundary.py +160 -0
- anyfesolver/general_contact/native_surface_front_precision.py +78 -0
- anyfesolver/general_contact/native_surface_front_work.py +118 -0
- anyfesolver/general_contact/native_surface_history.py +334 -0
- anyfesolver/general_contact/native_surface_normal.py +324 -0
- anyfesolver/general_contact/native_surface_patch.py +213 -0
- anyfesolver/general_contact/native_surface_path.py +348 -0
- anyfesolver/general_contact/native_surface_quadrature.py +212 -0
- anyfesolver/general_contact/native_surface_s3_friction.py +340 -0
- anyfesolver/general_contact/native_surface_support.py +776 -0
- anyfesolver/general_contact/native_surface_transaction.py +198 -0
- anyfesolver/general_contact/native_transient_multi_shell.py +108 -0
- anyfesolver/general_contact/native_transient_pair.py +61 -0
- anyfesolver/general_contact/native_transient_shell.py +44 -0
- anyfesolver/general_contact/normal_s3_skin_path.py +163 -0
- anyfesolver/general_contact/overlap.py +443 -0
- anyfesolver/general_contact/pair.py +466 -0
- anyfesolver/general_contact/patch_broadphase.py +111 -0
- anyfesolver/general_contact/patch_mortar.py +593 -0
- anyfesolver/general_contact/patch_sliding.py +644 -0
- anyfesolver/general_contact/plane_newmark_events.py +278 -0
- anyfesolver/general_contact/pointwise_patch.py +288 -0
- anyfesolver/general_contact/polynomial_roots.py +312 -0
- anyfesolver/general_contact/pressure_basis.py +241 -0
- anyfesolver/general_contact/pressure_diagnostics.py +155 -0
- anyfesolver/general_contact/pressure_overlay.py +182 -0
- anyfesolver/general_contact/pressure_space.py +51 -0
- anyfesolver/general_contact/q4_material_checkpoint.py +276 -0
- anyfesolver/general_contact/q4_overlap_local_bound.py +1111 -0
- anyfesolver/general_contact/q4_q4_overlap_derivatives.py +234 -0
- anyfesolver/general_contact/q4_q4_swept_bound.py +58 -0
- anyfesolver/general_contact/q4_s3_overlap_derivatives.py +1159 -0
- anyfesolver/general_contact/q4_s3_tiny_wedge.py +180 -0
- anyfesolver/general_contact/q4_skin_work.py +87 -0
- anyfesolver/general_contact/q4_source_mortar_energy.py +181 -0
- anyfesolver/general_contact/q4_source_overlap.py +401 -0
- anyfesolver/general_contact/q4_target_overlap.py +181 -0
- anyfesolver/general_contact/request_identity.py +192 -0
- anyfesolver/general_contact/rigid_translation.py +199 -0
- anyfesolver/general_contact/runtime.py +27 -0
- anyfesolver/general_contact/s3_friction_chart_interval.py +104 -0
- anyfesolver/general_contact/s3_friction_coverage.py +165 -0
- anyfesolver/general_contact/s3_friction_dyadic_interval.py +39 -0
- anyfesolver/general_contact/s3_friction_history_path.py +111 -0
- anyfesolver/general_contact/s3_friction_mesh_coverage.py +145 -0
- anyfesolver/general_contact/s3_friction_mesh_gap.py +74 -0
- anyfesolver/general_contact/s3_friction_mesh_monolithic.py +150 -0
- anyfesolver/general_contact/s3_friction_monolithic.py +121 -0
- anyfesolver/general_contact/s3_friction_moving_coverage.py +114 -0
- anyfesolver/general_contact/s3_friction_pair.py +237 -0
- anyfesolver/general_contact/s3_friction_point.py +129 -0
- anyfesolver/general_contact/s3_friction_prepared_path.py +254 -0
- anyfesolver/general_contact/s3_friction_replay.py +1094 -0
- anyfesolver/general_contact/s3_friction_rim_path.py +69 -0
- anyfesolver/general_contact/s3_friction_rim_transaction.py +23 -0
- anyfesolver/general_contact/s3_friction_static.py +267 -0
- anyfesolver/general_contact/s3_friction_swept_gap.py +112 -0
- anyfesolver/general_contact/s3_friction_touch.py +94 -0
- anyfesolver/general_contact/s3_friction_weak_pressure.py +66 -0
- anyfesolver/general_contact/s3_overlap_derivatives.py +220 -0
- anyfesolver/general_contact/s3_overlap_hermite_gap.py +180 -0
- anyfesolver/general_contact/s3_pair_static.py +343 -0
- anyfesolver/general_contact/s3_patch_augmented.py +2056 -0
- anyfesolver/general_contact/s3_patch_mortar_energy.py +545 -0
- anyfesolver/general_contact/s3_patch_static.py +1725 -0
- anyfesolver/general_contact/s3_pressure_hermite_bounds.py +395 -0
- anyfesolver/general_contact/s3_pressure_polygon_bounds.py +73 -0
- anyfesolver/general_contact/s3_q4_gap_resolution.py +191 -0
- anyfesolver/general_contact/s3_q4_overlap_derivatives.py +252 -0
- anyfesolver/general_contact/s3_q4_swept.py +56 -0
- anyfesolver/general_contact/s3_skin_work.py +101 -0
- anyfesolver/general_contact/s3_sliding_friction.py +640 -0
- anyfesolver/general_contact/s3_stable_plane_gap.py +43 -0
- anyfesolver/general_contact/seed_path_vertex_interval.py +323 -0
- anyfesolver/general_contact/semismooth.py +133 -0
- anyfesolver/general_contact/semismooth_block.py +147 -0
- anyfesolver/general_contact/semismooth_path.py +871 -0
- anyfesolver/general_contact/shell_pair_hermite_sweep.py +336 -0
- anyfesolver/general_contact/shell_sphere_temporal_bounds.py +305 -0
- anyfesolver/general_contact/skin_geometry.py +106 -0
- anyfesolver/general_contact/sliding.py +349 -0
- anyfesolver/general_contact/sphere.py +691 -0
- anyfesolver/general_contact/sphere_temporal_bounds.py +241 -0
- anyfesolver/general_contact/static_path.py +2608 -0
- anyfesolver/general_contact/static_results_archive.py +140 -0
- anyfesolver/general_contact/structural_state_bridge.py +196 -0
- anyfesolver/general_contact/supported_schur.py +594 -0
- anyfesolver/general_contact/swept_patch_broadphase.py +160 -0
- anyfesolver/general_contact/transient.py +2921 -0
- anyfesolver/general_contact/transient_results_archive.py +491 -0
- anyfesolver/general_contact/triangle_mortar_energy.py +280 -0
- anyfesolver/general_contact/triangle_pair_energy.py +211 -0
- anyfesolver/general_contact/triangulated_rigid.py +94 -0
- anyfesolver/general_contact/triangulated_rigid_static.py +399 -0
- anyfesolver/general_contact/warped_q4_plane.py +185 -0
- anyfesolver/general_contact/warped_q4_skin.py +302 -0
- anyfesolver/general_contact/warped_q4_static.py +331 -0
- anyfesolver/impact_performance.py +273 -0
- anyfesolver/impact_reduced_assembly.py +294 -0
- anyfesolver/imperfections.py +397 -0
- anyfesolver/inertia_relief.py +676 -0
- anyfesolver/initial_field_state.py +54 -0
- anyfesolver/jit_compiler.py +135 -0
- anyfesolver/kernel_warmup.py +228 -0
- anyfesolver/linalg.py +1002 -0
- anyfesolver/marine_contributions.py +634 -0
- anyfesolver/marine_coupled_equilibrium.py +292 -0
- anyfesolver/marine_equilibrium.py +405 -0
- anyfesolver/marine_hydro_coordinates.py +346 -0
- anyfesolver/marine_linear.py +549 -0
- anyfesolver/marine_link.py +306 -0
- anyfesolver/marine_mechanical.py +923 -0
- anyfesolver/marine_mooring.py +533 -0
- anyfesolver/marine_morison.py +331 -0
- anyfesolver/marine_potential_flow.py +403 -0
- anyfesolver/marine_rigid.py +397 -0
- anyfesolver/marine_seabed.py +122 -0
- anyfesolver/mass_properties.py +352 -0
- anyfesolver/material_curves.py +52 -0
- anyfesolver/materials.py +43 -0
- anyfesolver/matrix_assembly.py +7330 -0
- anyfesolver/mesh_gen.py +904 -0
- anyfesolver/mesh_load_bc_verification.py +612 -0
- anyfesolver/modal.py +2494 -0
- anyfesolver/nonlinear.py +341 -0
- anyfesolver/nonlinear_analysis_diagnostics.py +466 -0
- anyfesolver/nonlinear_element_evaluation.py +126 -0
- anyfesolver/nonlinear_performance.py +2094 -0
- anyfesolver/nonlinear_performance_batch_b.py +1173 -0
- anyfesolver/nonlinear_performance_batch_c.py +850 -0
- anyfesolver/nonlinear_performance_bootstrap.py +164 -0
- anyfesolver/nonlinear_reduced_assembly.py +806 -0
- anyfesolver/nonlinear_restart.py +1708 -0
- anyfesolver/nonlinear_state.py +2800 -0
- anyfesolver/nonlinear_static.py +9407 -0
- anyfesolver/outcomes.py +694 -0
- anyfesolver/plasticity.py +2087 -0
- anyfesolver/plasticity_qualification.py +758 -0
- anyfesolver/prepared_static.py +1129 -0
- anyfesolver/prepared_static_envelopes.py +389 -0
- anyfesolver/prepared_static_loads.py +1180 -0
- anyfesolver/prepared_static_measures.py +18 -0
- anyfesolver/prepared_static_numeric.py +247 -0
- anyfesolver/prepared_static_q4.py +297 -0
- anyfesolver/prepared_static_recovery.py +2068 -0
- anyfesolver/prepared_static_response.py +1013 -0
- anyfesolver/prepared_static_shared.py +226 -0
- anyfesolver/prepared_static_snapshot.py +323 -0
- anyfesolver/prepared_static_vectorized.py +866 -0
- anyfesolver/pressure_regions.py +287 -0
- anyfesolver/production_readiness.py +343 -0
- anyfesolver/quality_control.py +1487 -0
- anyfesolver/quantities.py +1289 -0
- anyfesolver/recovery.py +4217 -0
- anyfesolver/recovery_batches.py +1985 -0
- anyfesolver/recovery_policy.py +205 -0
- anyfesolver/recovery_s4.py +289 -0
- anyfesolver/recovery_shell_frames.py +102 -0
- anyfesolver/reference_cases.py +366 -0
- anyfesolver/result_capsule.py +2175 -0
- anyfesolver/results.py +752 -0
- anyfesolver/runtime.py +9819 -0
- anyfesolver/s3_reference_batch.py +1338 -0
- anyfesolver/s3_v2c_fast_assembly.py +544 -0
- anyfesolver/s3_v2d_fast_assembly.py +447 -0
- anyfesolver/s4_validity.py +354 -0
- anyfesolver/sections.py +67 -0
- anyfesolver/sesam_fem/__init__.py +55 -0
- anyfesolver/sesam_fem/__main__.py +80 -0
- anyfesolver/sesam_fem/diagnostics.py +5 -0
- anyfesolver/sesam_fem/document.py +39 -0
- anyfesolver/sesam_fem/exporter.py +9 -0
- anyfesolver/sesam_fem/importer.py +228 -0
- anyfesolver/sesam_fem/records.py +21 -0
- anyfesolver/sesam_fem/schema.py +35 -0
- anyfesolver/sesam_fem/sif_importer.py +9 -0
- anyfesolver/sesam_fem/validation.py +5 -0
- anyfesolver/sestra_deep_diagnostics.py +173 -0
- anyfesolver/sestra_mixed_verification.py +146 -0
- anyfesolver/sestra_structure_benchmarks.py +270 -0
- anyfesolver/sestra_three_case.py +215 -0
- anyfesolver/sestra_verification.py +523 -0
- anyfesolver/shell_benchmarks.py +367 -0
- anyfesolver/shell_formulations/director_field.py +799 -0
- anyfesolver/shell_formulations/geometry_provenance.py +921 -0
- anyfesolver/shell_formulations/mitc4_plus_d_quality.py +318 -0
- anyfesolver/shell_formulations/mitc4_plus_d_reference.py +837 -0
- anyfesolver/shell_formulations/mitc4_plus_d_scalar.py +209 -0
- anyfesolver/shell_formulations/protocol.py +222 -0
- anyfesolver/shell_formulations/q4_common.py +271 -0
- anyfesolver/shell_formulations/s4_restricted_policy.py +78 -0
- anyfesolver/shell_sections.py +394 -0
- anyfesolver/solid_submodel.py +930 -0
- anyfesolver/static_batch.py +662 -0
- anyfesolver/static_envelopes.py +250 -0
- anyfesolver/stiffened_shell.py +388 -0
- anyfesolver/submodel_transfer.py +1306 -0
- anyfesolver/test_cases.py +610 -0
- anyfesolver/threading_policy.py +431 -0
- anyfesolver/validation.py +719 -0
- anyfesolver/vectorized_beam.py +139 -0
- anyfesolver/vectorized_generalized_shell.py +448 -0
- anyfesolver/vectorized_hill48.py +956 -0
- anyfesolver/vectorized_nonlinear.py +360 -0
- anyfesolver/vectorized_stiffness.py +694 -0
- anyfesolver-0.5.0a1.dist-info/METADATA +374 -0
- anyfesolver-0.5.0a1.dist-info/RECORD +751 -0
- anyfesolver-0.5.0a1.dist-info/WHEEL +5 -0
- anyfesolver-0.5.0a1.dist-info/licenses/COPYRIGHT +1 -0
- anyfesolver-0.5.0a1.dist-info/licenses/LICENSE +373 -0
- anyfesolver-0.5.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +32 -0
- anyfesolver-0.5.0a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
"""Committed-state authority for the private mixed GE-Beam3 candidate.
|
|
2
|
+
|
|
3
|
+
This module owns the P2 restart boundary. Arrays are hashed and serialized as
|
|
4
|
+
typed, little-endian, contiguous byte strings so JSON number formatting can
|
|
5
|
+
never change a mechanics identity. The state remains private until the later
|
|
6
|
+
selector/package gate.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import hashlib
|
|
12
|
+
import json
|
|
13
|
+
import math
|
|
14
|
+
import re
|
|
15
|
+
from collections.abc import Mapping, Sequence
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from .beam_sections import generalized_beam_mass_matrix, generalized_beam_stiffness
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
GE_BEAM3_MIXED_CANDIDATE_ID = "CANDIDATE_GE_BEAM3_DC_MIXED_K1_MACRO_V2"
|
|
24
|
+
GE_BEAM3_MIXED_FORMULATION_ID = GE_BEAM3_MIXED_CANDIDATE_ID
|
|
25
|
+
GE_BEAM3_MIXED_CONDENSATION_ID = "TWO_CELL_18_LOCAL_SCHUR_V1"
|
|
26
|
+
GE_BEAM3_MIXED_QUADRATURE_ID = "K1_FORCE_GAUSS1_MOMENT_GAUSS2_V1"
|
|
27
|
+
GE_BEAM3_MIXED_REFERENCE_ID = "STRAIGHT_TWO_EQUAL_CELLS_V1"
|
|
28
|
+
GE_BEAM3_MIXED_ROTATION_ID = "ELEMENT_P0_VERTEX_HYBRID_SPATIAL_INCREMENT_V1"
|
|
29
|
+
|
|
30
|
+
STATE_SCHEMA = "anysolver.ge_beam3_mixed.committed_state.v1"
|
|
31
|
+
STATE_VERSION = 1
|
|
32
|
+
STATE_LAYOUT_ID = "GE_BEAM3_MIXED_Q18_SHARED_SO3_OPERATOR_STATION4_V1"
|
|
33
|
+
STATE_INTEGRITY_ID = "SHA256_CANONICAL_COMPLETE_STATE_EXCLUDING_DIGEST_V1"
|
|
34
|
+
SECTION_SCHEMA = "anysolver.ge-beam3-mixed.linear-section.v1"
|
|
35
|
+
COMMIT_STATUS = "COMMITTED_CONVERGED"
|
|
36
|
+
LOCAL_STATE_ROLE = "RECOVERED_CONDENSED_DIAGNOSTIC_NOT_RESTART_PREDICTOR"
|
|
37
|
+
SECTION_STATE_MODE = "STATELESS_LINEAR_SPD_6X6"
|
|
38
|
+
SECTION_STATION_IDS = ("CELL0_GP0", "CELL0_GP1", "CELL1_GP0", "CELL1_GP1")
|
|
39
|
+
|
|
40
|
+
_GEOMETRY_TOLERANCE = 1.0e-12
|
|
41
|
+
_SEMANTIC_TOLERANCE = 1.0e-11
|
|
42
|
+
_RELATIVE_ROTATION_LIMIT = 0.9 * math.pi
|
|
43
|
+
_SHA256 = re.compile(r"[0-9A-F]{64}\Z")
|
|
44
|
+
_HEX = re.compile(r"(?:[0-9A-F]{2})*\Z")
|
|
45
|
+
|
|
46
|
+
_ARRAY_FIELDS: dict[str, tuple[str, tuple[int, ...]]] = {
|
|
47
|
+
"committed_local_moments": ("<f8", (2, 2, 3)),
|
|
48
|
+
"committed_local_rotation_matrices": ("<f8", (2, 3, 3)),
|
|
49
|
+
"committed_nodal_rotation_matrices": ("<f8", (3, 3, 3)),
|
|
50
|
+
"committed_total_u": ("<f8", (18,)),
|
|
51
|
+
"node_ids": ("<i8", (3,)),
|
|
52
|
+
"reference_geometry": ("<f8", (3, 3)),
|
|
53
|
+
"reference_triad": ("<f8", (3, 3)),
|
|
54
|
+
"station_generalized_resultant": ("<f8", (4, 6)),
|
|
55
|
+
"station_generalized_strain": ("<f8", (4, 6)),
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
_STATE_KEYS = frozenset(
|
|
59
|
+
{
|
|
60
|
+
"candidate_id",
|
|
61
|
+
"commit_status",
|
|
62
|
+
"committed_local_moments",
|
|
63
|
+
"committed_local_rotation_matrices",
|
|
64
|
+
"committed_nodal_rotation_matrices",
|
|
65
|
+
"committed_total_u",
|
|
66
|
+
"condensation_id",
|
|
67
|
+
"element_id",
|
|
68
|
+
"element_identity_sha256",
|
|
69
|
+
"formulation_id",
|
|
70
|
+
"local_state_role",
|
|
71
|
+
"node_ids",
|
|
72
|
+
"quadrature_id",
|
|
73
|
+
"reference_geometry",
|
|
74
|
+
"reference_id",
|
|
75
|
+
"reference_triad",
|
|
76
|
+
"rotation_id",
|
|
77
|
+
"section_descriptor_sha256",
|
|
78
|
+
"section_state_mode",
|
|
79
|
+
"section_states",
|
|
80
|
+
"section_station_ids",
|
|
81
|
+
"state_integrity_id",
|
|
82
|
+
"state_integrity_sha256",
|
|
83
|
+
"state_layout_id",
|
|
84
|
+
"state_schema",
|
|
85
|
+
"state_version",
|
|
86
|
+
"station_generalized_resultant",
|
|
87
|
+
"station_generalized_strain",
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
_STATE_ENUMS = {
|
|
92
|
+
"candidate_id": GE_BEAM3_MIXED_CANDIDATE_ID,
|
|
93
|
+
"commit_status": COMMIT_STATUS,
|
|
94
|
+
"condensation_id": GE_BEAM3_MIXED_CONDENSATION_ID,
|
|
95
|
+
"formulation_id": GE_BEAM3_MIXED_FORMULATION_ID,
|
|
96
|
+
"local_state_role": LOCAL_STATE_ROLE,
|
|
97
|
+
"quadrature_id": GE_BEAM3_MIXED_QUADRATURE_ID,
|
|
98
|
+
"reference_id": GE_BEAM3_MIXED_REFERENCE_ID,
|
|
99
|
+
"rotation_id": GE_BEAM3_MIXED_ROTATION_ID,
|
|
100
|
+
"section_state_mode": SECTION_STATE_MODE,
|
|
101
|
+
"state_integrity_id": STATE_INTEGRITY_ID,
|
|
102
|
+
"state_layout_id": STATE_LAYOUT_ID,
|
|
103
|
+
"state_schema": STATE_SCHEMA,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class GeBeam3MixedCommittedStateError(ValueError):
|
|
108
|
+
"""A mixed GE-Beam3 state is malformed, stale, foreign, or inconsistent."""
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# Short compatibility spelling for element-side code.
|
|
112
|
+
GeBeam3MixedStateContractError = GeBeam3MixedCommittedStateError
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _is_sequence(value: Any) -> bool:
|
|
116
|
+
return isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _canonical_value(value: Any, *, path: str = "$") -> Any:
|
|
120
|
+
if isinstance(value, np.ndarray):
|
|
121
|
+
return encode_typed_array(value, path=path)
|
|
122
|
+
if isinstance(value, np.bool_):
|
|
123
|
+
return bool(value)
|
|
124
|
+
if isinstance(value, np.integer):
|
|
125
|
+
return int(value)
|
|
126
|
+
if isinstance(value, np.floating):
|
|
127
|
+
value = float(value)
|
|
128
|
+
if value is None or type(value) in (str, bool, int):
|
|
129
|
+
return value
|
|
130
|
+
if type(value) is float:
|
|
131
|
+
if not math.isfinite(value):
|
|
132
|
+
raise GeBeam3MixedCommittedStateError(f"nonfinite canonical value at {path}")
|
|
133
|
+
return value
|
|
134
|
+
if isinstance(value, Mapping):
|
|
135
|
+
made: dict[str, Any] = {}
|
|
136
|
+
for key, member in value.items():
|
|
137
|
+
if type(key) is not str:
|
|
138
|
+
raise GeBeam3MixedCommittedStateError(f"non-string canonical key at {path}")
|
|
139
|
+
if key in made:
|
|
140
|
+
raise GeBeam3MixedCommittedStateError(f"duplicate canonical key {key!r} at {path}")
|
|
141
|
+
made[key] = _canonical_value(member, path=f"{path}.{key}")
|
|
142
|
+
return made
|
|
143
|
+
if _is_sequence(value):
|
|
144
|
+
return [_canonical_value(member, path=f"{path}[{index}]") for index, member in enumerate(value)]
|
|
145
|
+
raise GeBeam3MixedCommittedStateError(
|
|
146
|
+
f"unsupported canonical value {type(value).__name__} at {path}"
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def canonical_json_bytes(value: Any) -> bytes:
|
|
151
|
+
"""Return sorted compact UTF-8 JSON with one LF and typed arrays."""
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
json.dumps(
|
|
155
|
+
_canonical_value(value),
|
|
156
|
+
allow_nan=False,
|
|
157
|
+
ensure_ascii=True,
|
|
158
|
+
separators=(",", ":"),
|
|
159
|
+
sort_keys=True,
|
|
160
|
+
)
|
|
161
|
+
+ "\n"
|
|
162
|
+
).encode("utf-8")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def canonical_sha256(value: Any) -> str:
|
|
166
|
+
return hashlib.sha256(canonical_json_bytes(value)).hexdigest().upper()
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def strict_canonical_json_loads(raw: bytes) -> Any:
|
|
170
|
+
"""Decode only the single frozen canonical JSON representation."""
|
|
171
|
+
|
|
172
|
+
if type(raw) is not bytes:
|
|
173
|
+
raise GeBeam3MixedCommittedStateError("canonical state input must be bytes")
|
|
174
|
+
if raw.startswith(b"\xef\xbb\xbf"):
|
|
175
|
+
raise GeBeam3MixedCommittedStateError("canonical state must not contain a BOM")
|
|
176
|
+
|
|
177
|
+
def unique(pairs: list[tuple[str, Any]]) -> dict[str, Any]:
|
|
178
|
+
made: dict[str, Any] = {}
|
|
179
|
+
for key, value in pairs:
|
|
180
|
+
if key in made:
|
|
181
|
+
raise GeBeam3MixedCommittedStateError(f"duplicate JSON key {key!r}")
|
|
182
|
+
made[key] = value
|
|
183
|
+
return made
|
|
184
|
+
|
|
185
|
+
def reject_constant(token: str) -> None:
|
|
186
|
+
raise GeBeam3MixedCommittedStateError(f"nonfinite JSON token {token}")
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
value = json.loads(
|
|
190
|
+
raw.decode("utf-8"),
|
|
191
|
+
object_pairs_hook=unique,
|
|
192
|
+
parse_constant=reject_constant,
|
|
193
|
+
)
|
|
194
|
+
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
195
|
+
raise GeBeam3MixedCommittedStateError("canonical state JSON is invalid") from exc
|
|
196
|
+
if canonical_json_bytes(value) != raw:
|
|
197
|
+
raise GeBeam3MixedCommittedStateError("state bytes are not canonical")
|
|
198
|
+
return value
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _canonical_dtype(dtype: Any) -> np.dtype[Any]:
|
|
202
|
+
made = np.dtype(dtype)
|
|
203
|
+
if made.kind == "f" and made.itemsize == 8:
|
|
204
|
+
return np.dtype("<f8")
|
|
205
|
+
if made.kind == "i" and made.itemsize == 8:
|
|
206
|
+
return np.dtype("<i8")
|
|
207
|
+
raise GeBeam3MixedCommittedStateError(
|
|
208
|
+
"typed state array dtype must be float64 or int64"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _owned_array(
|
|
213
|
+
value: Any,
|
|
214
|
+
dtype: str,
|
|
215
|
+
shape: tuple[int, ...],
|
|
216
|
+
label: str,
|
|
217
|
+
*,
|
|
218
|
+
strict_runtime_dtype: bool = False,
|
|
219
|
+
) -> np.ndarray:
|
|
220
|
+
if strict_runtime_dtype and not isinstance(value, np.ndarray):
|
|
221
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must be a typed numpy array")
|
|
222
|
+
try:
|
|
223
|
+
source = np.asarray(value)
|
|
224
|
+
except (TypeError, ValueError) as exc:
|
|
225
|
+
raise GeBeam3MixedCommittedStateError(f"{label} is not an array") from exc
|
|
226
|
+
expected = np.dtype(dtype)
|
|
227
|
+
if strict_runtime_dtype and _canonical_dtype(source.dtype) != expected:
|
|
228
|
+
raise GeBeam3MixedCommittedStateError(f"{label} has the wrong dtype")
|
|
229
|
+
if source.shape != shape:
|
|
230
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must have shape {shape}")
|
|
231
|
+
if expected.kind == "i":
|
|
232
|
+
if source.dtype.kind not in "iu" or source.dtype.kind == "b":
|
|
233
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must contain signed int64 values")
|
|
234
|
+
if source.dtype.kind == "u" and source.size and int(source.max()) > np.iinfo(np.int64).max:
|
|
235
|
+
raise GeBeam3MixedCommittedStateError(f"{label} exceeds signed int64")
|
|
236
|
+
else:
|
|
237
|
+
if source.dtype.kind not in "fiu":
|
|
238
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must contain binary64 values")
|
|
239
|
+
try:
|
|
240
|
+
made = np.array(source, dtype=expected, order="C", copy=True)
|
|
241
|
+
except (TypeError, ValueError, OverflowError) as exc:
|
|
242
|
+
raise GeBeam3MixedCommittedStateError(f"{label} cannot be represented exactly") from exc
|
|
243
|
+
if expected.kind == "f" and not np.all(np.isfinite(made)):
|
|
244
|
+
raise GeBeam3MixedCommittedStateError(f"{label} contains nonfinite values")
|
|
245
|
+
if expected.kind == "i" and source.dtype.kind in "iu" and not np.array_equal(made, source):
|
|
246
|
+
raise GeBeam3MixedCommittedStateError(f"{label} cannot be represented as signed int64")
|
|
247
|
+
made.setflags(write=False)
|
|
248
|
+
return made
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def encode_typed_array(value: Any, *, path: str = "$") -> dict[str, Any]:
|
|
252
|
+
"""Encode one canonical C-contiguous little-endian f8/i8 array."""
|
|
253
|
+
|
|
254
|
+
if not isinstance(value, np.ndarray):
|
|
255
|
+
raise GeBeam3MixedCommittedStateError(f"typed array required at {path}")
|
|
256
|
+
dtype = _canonical_dtype(value.dtype)
|
|
257
|
+
array = np.array(value, dtype=dtype, order="C", copy=True)
|
|
258
|
+
if dtype.kind == "f" and not np.all(np.isfinite(array)):
|
|
259
|
+
raise GeBeam3MixedCommittedStateError(f"nonfinite typed array at {path}")
|
|
260
|
+
return {
|
|
261
|
+
"data_hex": array.tobytes(order="C").hex().upper(),
|
|
262
|
+
"dtype": dtype.str,
|
|
263
|
+
"shape": [int(value) for value in array.shape],
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def decode_typed_array(
|
|
268
|
+
value: Any,
|
|
269
|
+
*,
|
|
270
|
+
dtype: str,
|
|
271
|
+
shape: tuple[int, ...],
|
|
272
|
+
label: str,
|
|
273
|
+
) -> np.ndarray:
|
|
274
|
+
"""Decode one exact typed-array JSON object into an owned read-only array."""
|
|
275
|
+
|
|
276
|
+
if not isinstance(value, Mapping) or set(value) != {"data_hex", "dtype", "shape"}:
|
|
277
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array object keys mismatch")
|
|
278
|
+
if value["dtype"] != dtype:
|
|
279
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array dtype mismatch")
|
|
280
|
+
raw_shape = value["shape"]
|
|
281
|
+
if not isinstance(raw_shape, list) or any(type(item) is not int or item < 0 for item in raw_shape):
|
|
282
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array shape is malformed")
|
|
283
|
+
if tuple(raw_shape) != shape:
|
|
284
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array shape mismatch")
|
|
285
|
+
data_hex = value["data_hex"]
|
|
286
|
+
if type(data_hex) is not str or _HEX.fullmatch(data_hex) is None:
|
|
287
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array data_hex is not uppercase hex")
|
|
288
|
+
expected_bytes = math.prod(shape) * np.dtype(dtype).itemsize
|
|
289
|
+
if len(data_hex) != 2 * expected_bytes:
|
|
290
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array byte count mismatch")
|
|
291
|
+
try:
|
|
292
|
+
data = bytes.fromhex(data_hex)
|
|
293
|
+
except ValueError as exc: # defensive; the expression above is authoritative
|
|
294
|
+
raise GeBeam3MixedCommittedStateError(f"{label} typed array data_hex is invalid") from exc
|
|
295
|
+
made = np.frombuffer(data, dtype=np.dtype(dtype)).copy().reshape(shape)
|
|
296
|
+
if np.dtype(dtype).kind == "f" and not np.all(np.isfinite(made)):
|
|
297
|
+
raise GeBeam3MixedCommittedStateError(f"{label} contains nonfinite values")
|
|
298
|
+
made.setflags(write=False)
|
|
299
|
+
return made
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def _state_array(value: Any, name: str) -> np.ndarray:
|
|
303
|
+
dtype, shape = _ARRAY_FIELDS[name]
|
|
304
|
+
if isinstance(value, Mapping):
|
|
305
|
+
return decode_typed_array(value, dtype=dtype, shape=shape, label=name)
|
|
306
|
+
return _owned_array(value, dtype, shape, name, strict_runtime_dtype=True)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _sha(value: Any, label: str) -> str:
|
|
310
|
+
if type(value) is not str or _SHA256.fullmatch(value) is None:
|
|
311
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must be uppercase SHA-256")
|
|
312
|
+
return value
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _integer(value: Any, label: str) -> int:
|
|
316
|
+
if type(value) is not int:
|
|
317
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must be an integer, not a boolean")
|
|
318
|
+
return value
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _proper_rotation(matrix: np.ndarray, label: str) -> None:
|
|
322
|
+
defect = float(np.linalg.norm(matrix.T @ matrix - np.eye(3), ord=np.inf))
|
|
323
|
+
determinant = float(np.linalg.det(matrix))
|
|
324
|
+
if defect > 1.0e-12 or determinant <= 0.0 or abs(determinant - 1.0) > 1.0e-12:
|
|
325
|
+
raise GeBeam3MixedCommittedStateError(f"{label} is not a proper rotation")
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _validate_reference(
|
|
329
|
+
geometry: np.ndarray,
|
|
330
|
+
triad: np.ndarray,
|
|
331
|
+
orientation: Any,
|
|
332
|
+
axis_direction: Any,
|
|
333
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
334
|
+
chord = geometry[2] - geometry[0]
|
|
335
|
+
length = float(np.linalg.norm(chord))
|
|
336
|
+
if not math.isfinite(length) or length <= 0.0:
|
|
337
|
+
raise GeBeam3MixedCommittedStateError("reference geometry has coincident ends")
|
|
338
|
+
if float(np.linalg.norm(geometry[1] - 0.5 * (geometry[0] + geometry[2]))) > _GEOMETRY_TOLERANCE * length:
|
|
339
|
+
raise GeBeam3MixedCommittedStateError("reference middle node is not the exact midpoint within tolerance")
|
|
340
|
+
first = geometry[1] - geometry[0]
|
|
341
|
+
second = geometry[2] - geometry[1]
|
|
342
|
+
if float(np.linalg.norm(np.cross(first, chord))) > _GEOMETRY_TOLERANCE * length * length:
|
|
343
|
+
raise GeBeam3MixedCommittedStateError("reference geometry is not collinear")
|
|
344
|
+
if float(np.linalg.norm(np.cross(second, chord))) > _GEOMETRY_TOLERANCE * length * length:
|
|
345
|
+
raise GeBeam3MixedCommittedStateError("reference geometry is not collinear")
|
|
346
|
+
_proper_rotation(triad, "reference_triad")
|
|
347
|
+
e1 = chord / length
|
|
348
|
+
if float(np.linalg.norm(triad[:, 0] - e1, ord=np.inf)) > _GEOMETRY_TOLERANCE:
|
|
349
|
+
raise GeBeam3MixedCommittedStateError("reference triad first column is not chord-aligned")
|
|
350
|
+
orient = _owned_array(orientation, "<f8", (3,), "reference_orientation")
|
|
351
|
+
projected = orient - float(orient @ e1) * e1
|
|
352
|
+
projected_norm = float(np.linalg.norm(projected))
|
|
353
|
+
if projected_norm <= _GEOMETRY_TOLERANCE * float(np.linalg.norm(orient)):
|
|
354
|
+
raise GeBeam3MixedCommittedStateError("reference orientation is parallel to the chord")
|
|
355
|
+
if float(np.linalg.norm(triad[:, 1] - projected / projected_norm, ord=np.inf)) > _GEOMETRY_TOLERANCE:
|
|
356
|
+
raise GeBeam3MixedCommittedStateError("reference triad does not reproduce the physical orientation")
|
|
357
|
+
axis = _owned_array(axis_direction, "<f8", (3,), "reference_axis_direction")
|
|
358
|
+
axis_norm = float(np.linalg.norm(axis))
|
|
359
|
+
if axis_norm <= 0.0 or abs(abs(float((axis / axis_norm) @ e1)) - 1.0) > _GEOMETRY_TOLERANCE:
|
|
360
|
+
raise GeBeam3MixedCommittedStateError("reference axis authority is not parallel to the chord")
|
|
361
|
+
return orient, axis
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _positive_definite_matrix(value: Any, label: str) -> np.ndarray:
|
|
365
|
+
made = _owned_array(value, "<f8", (6, 6), label)
|
|
366
|
+
diagonal = np.diag(made)
|
|
367
|
+
if np.any(diagonal <= 0.0):
|
|
368
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must have a positive diagonal")
|
|
369
|
+
scale = 1.0 / np.sqrt(diagonal)
|
|
370
|
+
normalized = scale[:, None] * made * scale[None, :]
|
|
371
|
+
if not np.allclose(normalized, normalized.T, rtol=1.0e-10, atol=1.0e-12):
|
|
372
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must be symmetric")
|
|
373
|
+
if float(np.linalg.eigvalsh(0.5 * (normalized + normalized.T))[0]) <= 1.0e-12:
|
|
374
|
+
raise GeBeam3MixedCommittedStateError(f"{label} must be positive definite")
|
|
375
|
+
result = np.array(0.5 * (made + made.T), dtype="<f8", order="C", copy=True)
|
|
376
|
+
result.setflags(write=False)
|
|
377
|
+
return result
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def section_descriptor_payload(
|
|
381
|
+
*, section_name: str, section_stiffness: Any, section_mass: Any
|
|
382
|
+
) -> dict[str, Any]:
|
|
383
|
+
if type(section_name) is not str:
|
|
384
|
+
raise GeBeam3MixedCommittedStateError("section_name must be a string")
|
|
385
|
+
return {
|
|
386
|
+
"mass_matrix_per_reference_length": _positive_definite_matrix(section_mass, "section mass"),
|
|
387
|
+
"name": section_name,
|
|
388
|
+
"schema": SECTION_SCHEMA,
|
|
389
|
+
"stiffness_matrix": _positive_definite_matrix(section_stiffness, "section stiffness"),
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def section_descriptor_sha256(
|
|
394
|
+
*, section_name: str, section_stiffness: Any, section_mass: Any
|
|
395
|
+
) -> str:
|
|
396
|
+
return canonical_sha256(
|
|
397
|
+
section_descriptor_payload(
|
|
398
|
+
section_name=section_name,
|
|
399
|
+
section_stiffness=section_stiffness,
|
|
400
|
+
section_mass=section_mass,
|
|
401
|
+
)
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def element_identity_payload(
|
|
406
|
+
*,
|
|
407
|
+
node_ids: Any,
|
|
408
|
+
reference_geometry: Any,
|
|
409
|
+
reference_triad: Any,
|
|
410
|
+
reference_orientation: Any,
|
|
411
|
+
reference_axis_direction: Any,
|
|
412
|
+
section_descriptor_sha256_value: str,
|
|
413
|
+
) -> dict[str, Any]:
|
|
414
|
+
nodes = _owned_array(node_ids, "<i8", (3,), "node_ids")
|
|
415
|
+
if len(set(int(value) for value in nodes)) != 3:
|
|
416
|
+
raise GeBeam3MixedCommittedStateError("node_ids must contain three distinct IDs")
|
|
417
|
+
geometry = _owned_array(reference_geometry, "<f8", (3, 3), "reference_geometry")
|
|
418
|
+
triad = _owned_array(reference_triad, "<f8", (3, 3), "reference_triad")
|
|
419
|
+
orientation, axis = _validate_reference(geometry, triad, reference_orientation, reference_axis_direction)
|
|
420
|
+
return {
|
|
421
|
+
"candidate_id": GE_BEAM3_MIXED_CANDIDATE_ID,
|
|
422
|
+
"condensation_id": GE_BEAM3_MIXED_CONDENSATION_ID,
|
|
423
|
+
"node_ids": nodes,
|
|
424
|
+
"quadrature_id": GE_BEAM3_MIXED_QUADRATURE_ID,
|
|
425
|
+
"reference_axis_direction": axis,
|
|
426
|
+
"reference_geometry": geometry,
|
|
427
|
+
"reference_id": GE_BEAM3_MIXED_REFERENCE_ID,
|
|
428
|
+
"reference_orientation": orientation,
|
|
429
|
+
"reference_triad": triad,
|
|
430
|
+
"rotation_id": GE_BEAM3_MIXED_ROTATION_ID,
|
|
431
|
+
"section_descriptor_sha256": _sha(
|
|
432
|
+
section_descriptor_sha256_value, "section_descriptor_sha256"
|
|
433
|
+
),
|
|
434
|
+
"state_layout_id": STATE_LAYOUT_ID,
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def element_identity_sha256(**kwargs: Any) -> str:
|
|
439
|
+
return canonical_sha256(element_identity_payload(**kwargs))
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def model_bound_identity(element: Any, mesh: Any) -> dict[str, Any]:
|
|
443
|
+
"""Recompute the complete P2 identity from an element and current model."""
|
|
444
|
+
|
|
445
|
+
geometry = _owned_array(element.get_node_coordinates(mesh), "<f8", (3, 3), "reference_geometry")
|
|
446
|
+
triad = _owned_array(element.reference_triad(mesh), "<f8", (3, 3), "reference_triad")
|
|
447
|
+
# Identity follows the same physical-axis polarity convention as mechanics.
|
|
448
|
+
# A reversed coupled element stores the effective transformed section, not
|
|
449
|
+
# the untransformed section object. Prefer the element-owned methods so the
|
|
450
|
+
# identity cannot drift from its actual energy/mass operators.
|
|
451
|
+
stiffness_provider = getattr(element, "_section_stiffness", None)
|
|
452
|
+
mass_provider = getattr(element, "_section_mass", None)
|
|
453
|
+
stiffness = (
|
|
454
|
+
stiffness_provider(mesh)
|
|
455
|
+
if callable(stiffness_provider)
|
|
456
|
+
else generalized_beam_stiffness(element.generalized_section)
|
|
457
|
+
)
|
|
458
|
+
mass = (
|
|
459
|
+
mass_provider(mesh)
|
|
460
|
+
if callable(mass_provider)
|
|
461
|
+
else generalized_beam_mass_matrix(element.generalized_section)
|
|
462
|
+
)
|
|
463
|
+
if mass is None:
|
|
464
|
+
raise GeBeam3MixedCommittedStateError(
|
|
465
|
+
"mixed GE-Beam3 P2 state requires an authoritative generalized section mass"
|
|
466
|
+
)
|
|
467
|
+
axis = getattr(element, "reference_axis_direction", None)
|
|
468
|
+
if axis is None:
|
|
469
|
+
# The element's state authority uses the directed reference chord for a
|
|
470
|
+
# reversal-insensitive section whose constructor did not require an
|
|
471
|
+
# explicit physical-axis authority. Persist that concrete vector: the
|
|
472
|
+
# frozen typed preimage does not admit null outside section_states.
|
|
473
|
+
axis = triad[:, 0]
|
|
474
|
+
descriptor = section_descriptor_payload(
|
|
475
|
+
section_name=str(element.generalized_section.name),
|
|
476
|
+
section_stiffness=stiffness,
|
|
477
|
+
section_mass=mass,
|
|
478
|
+
)
|
|
479
|
+
descriptor_hash = canonical_sha256(descriptor)
|
|
480
|
+
identity = element_identity_payload(
|
|
481
|
+
node_ids=np.asarray(element.node_ids, dtype="<i8"),
|
|
482
|
+
reference_geometry=geometry,
|
|
483
|
+
reference_triad=triad,
|
|
484
|
+
reference_orientation=element.reference_orientation,
|
|
485
|
+
reference_axis_direction=axis,
|
|
486
|
+
section_descriptor_sha256_value=descriptor_hash,
|
|
487
|
+
)
|
|
488
|
+
return {
|
|
489
|
+
"element_identity_payload": identity,
|
|
490
|
+
"element_identity_sha256": canonical_sha256(identity),
|
|
491
|
+
"reference_geometry": geometry,
|
|
492
|
+
"reference_triad": triad,
|
|
493
|
+
"section_descriptor": descriptor,
|
|
494
|
+
"section_descriptor_sha256": descriptor_hash,
|
|
495
|
+
"section_mass": descriptor["mass_matrix_per_reference_length"],
|
|
496
|
+
"section_stiffness": descriptor["stiffness_matrix"],
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def _normalized_close(left: np.ndarray, right: np.ndarray, tolerance: float = _SEMANTIC_TOLERANCE) -> bool:
|
|
501
|
+
# ``numpy.linalg.norm(..., ord=inf)`` is defined only through matrices;
|
|
502
|
+
# registered state arrays also include rank-three cell/endpoint records.
|
|
503
|
+
# The componentwise infinity norm is the intended normalized invariant for
|
|
504
|
+
# every registered shape.
|
|
505
|
+
scale = max(
|
|
506
|
+
1.0,
|
|
507
|
+
float(np.max(np.abs(left), initial=0.0)),
|
|
508
|
+
float(np.max(np.abs(right), initial=0.0)),
|
|
509
|
+
)
|
|
510
|
+
difference = float(np.max(np.abs(left - right), initial=0.0))
|
|
511
|
+
return bool(difference <= tolerance * scale)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def _bitwise_equal(left: np.ndarray, right: np.ndarray) -> bool:
|
|
515
|
+
return bool(left.dtype == right.dtype and left.shape == right.shape and left.tobytes(order="C") == right.tobytes(order="C"))
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def _validate_rotations(state: Mapping[str, Any]) -> None:
|
|
519
|
+
triad = state["reference_triad"]
|
|
520
|
+
nodal = state["committed_nodal_rotation_matrices"]
|
|
521
|
+
local = state["committed_local_rotation_matrices"]
|
|
522
|
+
for index, matrix in enumerate(nodal):
|
|
523
|
+
_proper_rotation(matrix, f"committed_nodal_rotation_matrices[{index}]")
|
|
524
|
+
for index, matrix in enumerate(local):
|
|
525
|
+
_proper_rotation(matrix, f"committed_local_rotation_matrices[{index}]")
|
|
526
|
+
absolute = np.einsum("nij,jk->nik", nodal, triad)
|
|
527
|
+
for left, right in ((0, 1), (1, 2)):
|
|
528
|
+
relative = absolute[left].T @ absolute[right]
|
|
529
|
+
cosine = max(-1.0, min(1.0, 0.5 * (float(np.trace(relative)) - 1.0)))
|
|
530
|
+
if math.acos(cosine) >= _RELATIVE_ROTATION_LIMIT:
|
|
531
|
+
raise GeBeam3MixedCommittedStateError(
|
|
532
|
+
f"adjacent absolute material frames {left + 1}-{right + 1} exceed the rotation domain"
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def _normalize_state_structure(state: Mapping[str, Any]) -> dict[str, Any]:
|
|
537
|
+
if not isinstance(state, Mapping):
|
|
538
|
+
raise GeBeam3MixedCommittedStateError("committed mixed GE-Beam3 state must be a mapping")
|
|
539
|
+
if set(state) != _STATE_KEYS:
|
|
540
|
+
missing = sorted(_STATE_KEYS - set(state))
|
|
541
|
+
extra = sorted(set(state) - _STATE_KEYS)
|
|
542
|
+
raise GeBeam3MixedCommittedStateError(
|
|
543
|
+
f"state keys mismatch; missing={missing}, extra={extra}"
|
|
544
|
+
)
|
|
545
|
+
made: dict[str, Any] = {}
|
|
546
|
+
for key, expected in _STATE_ENUMS.items():
|
|
547
|
+
if type(state[key]) is not str or state[key] != expected:
|
|
548
|
+
raise GeBeam3MixedCommittedStateError(f"state enum {key} mismatch")
|
|
549
|
+
made[key] = state[key]
|
|
550
|
+
made["state_version"] = _integer(state["state_version"], "state_version")
|
|
551
|
+
if made["state_version"] != STATE_VERSION:
|
|
552
|
+
raise GeBeam3MixedCommittedStateError("state version mismatch")
|
|
553
|
+
made["element_id"] = _integer(state["element_id"], "element_id")
|
|
554
|
+
made["element_identity_sha256"] = _sha(state["element_identity_sha256"], "element_identity_sha256")
|
|
555
|
+
made["section_descriptor_sha256"] = _sha(state["section_descriptor_sha256"], "section_descriptor_sha256")
|
|
556
|
+
made["state_integrity_sha256"] = _sha(state["state_integrity_sha256"], "state_integrity_sha256")
|
|
557
|
+
if type(state["section_station_ids"]) is not list or tuple(state["section_station_ids"]) != SECTION_STATION_IDS:
|
|
558
|
+
raise GeBeam3MixedCommittedStateError("section station IDs mismatch")
|
|
559
|
+
made["section_station_ids"] = list(SECTION_STATION_IDS)
|
|
560
|
+
if type(state["section_states"]) is not list or state["section_states"] != [None, None, None, None]:
|
|
561
|
+
raise GeBeam3MixedCommittedStateError("stateless section_states must be exactly four nulls")
|
|
562
|
+
made["section_states"] = [None, None, None, None]
|
|
563
|
+
for name in _ARRAY_FIELDS:
|
|
564
|
+
made[name] = _state_array(state[name], name)
|
|
565
|
+
return made
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
def _state_integrity_sha256(state: Mapping[str, Any]) -> str:
|
|
569
|
+
return canonical_sha256(
|
|
570
|
+
{key: value for key, value in state.items() if key != "state_integrity_sha256"}
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def seal_committed_ge_beam3_mixed_state(state: Mapping[str, Any]) -> dict[str, Any]:
|
|
575
|
+
"""Own, normalize, and integrity-seal a complete state mapping."""
|
|
576
|
+
|
|
577
|
+
if not isinstance(state, Mapping):
|
|
578
|
+
raise GeBeam3MixedCommittedStateError("committed mixed GE-Beam3 state must be a mapping")
|
|
579
|
+
expected_without_digest = _STATE_KEYS - {"state_integrity_sha256"}
|
|
580
|
+
supplied = set(state)
|
|
581
|
+
if supplied == expected_without_digest:
|
|
582
|
+
provisional = dict(state)
|
|
583
|
+
provisional["state_integrity_sha256"] = "0" * 64
|
|
584
|
+
elif supplied == _STATE_KEYS:
|
|
585
|
+
provisional = dict(state)
|
|
586
|
+
else:
|
|
587
|
+
missing = sorted(expected_without_digest - supplied)
|
|
588
|
+
extra = sorted(supplied - _STATE_KEYS)
|
|
589
|
+
raise GeBeam3MixedCommittedStateError(
|
|
590
|
+
f"state keys mismatch before sealing; missing={missing}, extra={extra}"
|
|
591
|
+
)
|
|
592
|
+
normalized = _normalize_state_structure(provisional)
|
|
593
|
+
normalized["state_integrity_sha256"] = _state_integrity_sha256(normalized)
|
|
594
|
+
return normalized
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
def initialize_ge_beam3_mixed_state(
|
|
598
|
+
*,
|
|
599
|
+
element_id: int,
|
|
600
|
+
node_ids: Any,
|
|
601
|
+
reference_geometry: Any,
|
|
602
|
+
reference_triad: Any,
|
|
603
|
+
reference_orientation: Any,
|
|
604
|
+
reference_axis_direction: Any,
|
|
605
|
+
section_name: str,
|
|
606
|
+
section_stiffness: Any,
|
|
607
|
+
section_mass: Any,
|
|
608
|
+
committed_total_u: Any | None = None,
|
|
609
|
+
committed_nodal_rotation_matrices: Any | None = None,
|
|
610
|
+
committed_local_rotation_matrices: Any | None = None,
|
|
611
|
+
committed_local_moments: Any | None = None,
|
|
612
|
+
station_generalized_strain: Any | None = None,
|
|
613
|
+
station_generalized_resultant: Any | None = None,
|
|
614
|
+
) -> dict[str, Any]:
|
|
615
|
+
"""Build an owned sealed committed state from model and recovered fields."""
|
|
616
|
+
|
|
617
|
+
_integer(element_id, "element_id")
|
|
618
|
+
nodes = _owned_array(node_ids, "<i8", (3,), "node_ids")
|
|
619
|
+
geometry = _owned_array(reference_geometry, "<f8", (3, 3), "reference_geometry")
|
|
620
|
+
triad = _owned_array(reference_triad, "<f8", (3, 3), "reference_triad")
|
|
621
|
+
descriptor = section_descriptor_payload(
|
|
622
|
+
section_name=section_name,
|
|
623
|
+
section_stiffness=section_stiffness,
|
|
624
|
+
section_mass=section_mass,
|
|
625
|
+
)
|
|
626
|
+
descriptor_hash = canonical_sha256(descriptor)
|
|
627
|
+
identity_hash = element_identity_sha256(
|
|
628
|
+
node_ids=nodes,
|
|
629
|
+
reference_geometry=geometry,
|
|
630
|
+
reference_triad=triad,
|
|
631
|
+
reference_orientation=reference_orientation,
|
|
632
|
+
reference_axis_direction=reference_axis_direction,
|
|
633
|
+
section_descriptor_sha256_value=descriptor_hash,
|
|
634
|
+
)
|
|
635
|
+
total_u = np.zeros(18, dtype="<f8") if committed_total_u is None else committed_total_u
|
|
636
|
+
nodal = np.repeat(np.eye(3, dtype="<f8")[None, :, :], 3, axis=0) if committed_nodal_rotation_matrices is None else committed_nodal_rotation_matrices
|
|
637
|
+
local = np.repeat(triad[None, :, :], 2, axis=0) if committed_local_rotation_matrices is None else committed_local_rotation_matrices
|
|
638
|
+
moments = np.zeros((2, 2, 3), dtype="<f8") if committed_local_moments is None else committed_local_moments
|
|
639
|
+
strains = np.zeros((4, 6), dtype="<f8") if station_generalized_strain is None else station_generalized_strain
|
|
640
|
+
resultants = np.asarray(strains, dtype="<f8") @ np.asarray(descriptor["stiffness_matrix"], dtype="<f8").T if station_generalized_resultant is None else station_generalized_resultant
|
|
641
|
+
state = {
|
|
642
|
+
**_STATE_ENUMS,
|
|
643
|
+
"committed_local_moments": _owned_array(moments, "<f8", (2, 2, 3), "committed_local_moments"),
|
|
644
|
+
"committed_local_rotation_matrices": _owned_array(local, "<f8", (2, 3, 3), "committed_local_rotation_matrices"),
|
|
645
|
+
"committed_nodal_rotation_matrices": _owned_array(nodal, "<f8", (3, 3, 3), "committed_nodal_rotation_matrices"),
|
|
646
|
+
"committed_total_u": _owned_array(total_u, "<f8", (18,), "committed_total_u"),
|
|
647
|
+
"element_id": element_id,
|
|
648
|
+
"element_identity_sha256": identity_hash,
|
|
649
|
+
"node_ids": nodes,
|
|
650
|
+
"reference_geometry": geometry,
|
|
651
|
+
"reference_triad": triad,
|
|
652
|
+
"section_descriptor_sha256": descriptor_hash,
|
|
653
|
+
"section_states": [None, None, None, None],
|
|
654
|
+
"section_station_ids": list(SECTION_STATION_IDS),
|
|
655
|
+
"state_version": STATE_VERSION,
|
|
656
|
+
"station_generalized_resultant": _owned_array(resultants, "<f8", (4, 6), "station_generalized_resultant"),
|
|
657
|
+
"station_generalized_strain": _owned_array(strains, "<f8", (4, 6), "station_generalized_strain"),
|
|
658
|
+
}
|
|
659
|
+
sealed = seal_committed_ge_beam3_mixed_state(state)
|
|
660
|
+
return validate_committed_ge_beam3_mixed_state(
|
|
661
|
+
sealed,
|
|
662
|
+
element_id=element_id,
|
|
663
|
+
node_ids=nodes,
|
|
664
|
+
reference_geometry=geometry,
|
|
665
|
+
reference_triad=triad,
|
|
666
|
+
reference_orientation=reference_orientation,
|
|
667
|
+
reference_axis_direction=reference_axis_direction,
|
|
668
|
+
section_name=section_name,
|
|
669
|
+
section_stiffness=descriptor["stiffness_matrix"],
|
|
670
|
+
section_mass=descriptor["mass_matrix_per_reference_length"],
|
|
671
|
+
expected_committed_total_u=total_u,
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
def validate_committed_ge_beam3_mixed_state(
|
|
676
|
+
state: Mapping[str, Any],
|
|
677
|
+
*,
|
|
678
|
+
element_id: int,
|
|
679
|
+
node_ids: Any,
|
|
680
|
+
reference_geometry: Any,
|
|
681
|
+
reference_triad: Any,
|
|
682
|
+
reference_orientation: Any,
|
|
683
|
+
reference_axis_direction: Any,
|
|
684
|
+
section_name: str,
|
|
685
|
+
section_stiffness: Any,
|
|
686
|
+
section_mass: Any,
|
|
687
|
+
expected_committed_total_u: Any | None = None,
|
|
688
|
+
expected_local_state: Mapping[str, Any] | None = None,
|
|
689
|
+
) -> dict[str, Any]:
|
|
690
|
+
"""Validate exact identity/integrity and local constitutive invariants."""
|
|
691
|
+
|
|
692
|
+
normalized = _normalize_state_structure(state)
|
|
693
|
+
if normalized["state_integrity_sha256"] != _state_integrity_sha256(normalized):
|
|
694
|
+
raise GeBeam3MixedCommittedStateError("committed state integrity mismatch")
|
|
695
|
+
expected_element_id = _integer(element_id, "element_id")
|
|
696
|
+
nodes = _owned_array(node_ids, "<i8", (3,), "expected node_ids")
|
|
697
|
+
geometry = _owned_array(reference_geometry, "<f8", (3, 3), "expected reference_geometry")
|
|
698
|
+
triad = _owned_array(reference_triad, "<f8", (3, 3), "expected reference_triad")
|
|
699
|
+
descriptor = section_descriptor_payload(
|
|
700
|
+
section_name=section_name,
|
|
701
|
+
section_stiffness=section_stiffness,
|
|
702
|
+
section_mass=section_mass,
|
|
703
|
+
)
|
|
704
|
+
descriptor_hash = canonical_sha256(descriptor)
|
|
705
|
+
identity_hash = element_identity_sha256(
|
|
706
|
+
node_ids=nodes,
|
|
707
|
+
reference_geometry=geometry,
|
|
708
|
+
reference_triad=triad,
|
|
709
|
+
reference_orientation=reference_orientation,
|
|
710
|
+
reference_axis_direction=reference_axis_direction,
|
|
711
|
+
section_descriptor_sha256_value=descriptor_hash,
|
|
712
|
+
)
|
|
713
|
+
if normalized["element_id"] != expected_element_id:
|
|
714
|
+
raise GeBeam3MixedCommittedStateError("element ID binding mismatch")
|
|
715
|
+
if not _bitwise_equal(normalized["node_ids"], nodes):
|
|
716
|
+
raise GeBeam3MixedCommittedStateError("connectivity binding mismatch")
|
|
717
|
+
if not _bitwise_equal(normalized["reference_geometry"], geometry):
|
|
718
|
+
raise GeBeam3MixedCommittedStateError("reference geometry bit pattern mismatch")
|
|
719
|
+
if not _bitwise_equal(normalized["reference_triad"], triad):
|
|
720
|
+
raise GeBeam3MixedCommittedStateError("reference triad bit pattern mismatch")
|
|
721
|
+
if normalized["section_descriptor_sha256"] != descriptor_hash:
|
|
722
|
+
raise GeBeam3MixedCommittedStateError("section descriptor binding mismatch")
|
|
723
|
+
if normalized["element_identity_sha256"] != identity_hash:
|
|
724
|
+
raise GeBeam3MixedCommittedStateError("element identity binding mismatch")
|
|
725
|
+
if expected_committed_total_u is not None:
|
|
726
|
+
expected_u = _owned_array(expected_committed_total_u, "<f8", (18,), "expected committed_total_u")
|
|
727
|
+
if not _bitwise_equal(normalized["committed_total_u"], expected_u):
|
|
728
|
+
raise GeBeam3MixedCommittedStateError("committed displacement binding mismatch")
|
|
729
|
+
_validate_rotations(normalized)
|
|
730
|
+
stiffness = descriptor["stiffness_matrix"]
|
|
731
|
+
expected_resultants = normalized["station_generalized_strain"] @ stiffness.T
|
|
732
|
+
if not _normalized_close(normalized["station_generalized_resultant"], expected_resultants):
|
|
733
|
+
raise GeBeam3MixedCommittedStateError("station resultants are not section stiffness times strain")
|
|
734
|
+
expected_moments = normalized["station_generalized_resultant"][:, 3:6].reshape(2, 2, 3)
|
|
735
|
+
if not _normalized_close(normalized["committed_local_moments"], expected_moments):
|
|
736
|
+
raise GeBeam3MixedCommittedStateError("local moments do not match sided station resultants")
|
|
737
|
+
if expected_local_state is not None:
|
|
738
|
+
if not isinstance(expected_local_state, Mapping):
|
|
739
|
+
raise GeBeam3MixedCommittedStateError("expected_local_state must be a mapping")
|
|
740
|
+
comparisons = {
|
|
741
|
+
"committed_local_rotation_matrices": (2, 3, 3),
|
|
742
|
+
"committed_local_moments": (2, 2, 3),
|
|
743
|
+
"station_generalized_strain": (4, 6),
|
|
744
|
+
"station_generalized_resultant": (4, 6),
|
|
745
|
+
}
|
|
746
|
+
if set(expected_local_state) != set(comparisons):
|
|
747
|
+
raise GeBeam3MixedCommittedStateError("expected local-state keys mismatch")
|
|
748
|
+
for name, shape in comparisons.items():
|
|
749
|
+
expected = _owned_array(expected_local_state[name], "<f8", shape, f"expected {name}")
|
|
750
|
+
if not _normalized_close(normalized[name], expected):
|
|
751
|
+
raise GeBeam3MixedCommittedStateError(f"recomputed local state mismatch for {name}")
|
|
752
|
+
return normalized
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
def serialize_ge_beam3_mixed_state(state: Mapping[str, Any]) -> bytes:
|
|
756
|
+
normalized = _normalize_state_structure(state)
|
|
757
|
+
if normalized["state_integrity_sha256"] != _state_integrity_sha256(normalized):
|
|
758
|
+
raise GeBeam3MixedCommittedStateError("cannot serialize state with invalid integrity")
|
|
759
|
+
return canonical_json_bytes(normalized)
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
def deserialize_ge_beam3_mixed_state(raw: bytes) -> dict[str, Any]:
|
|
763
|
+
decoded = strict_canonical_json_loads(raw)
|
|
764
|
+
if not isinstance(decoded, Mapping):
|
|
765
|
+
raise GeBeam3MixedCommittedStateError("restart payload must decode to a mapping")
|
|
766
|
+
normalized = _normalize_state_structure(decoded)
|
|
767
|
+
if normalized["state_integrity_sha256"] != _state_integrity_sha256(normalized):
|
|
768
|
+
raise GeBeam3MixedCommittedStateError("restart state integrity mismatch")
|
|
769
|
+
return normalized
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
# Concise aliases used by element-side code and tests.
|
|
773
|
+
build_committed_state = initialize_ge_beam3_mixed_state
|
|
774
|
+
seal_committed_state = seal_committed_ge_beam3_mixed_state
|
|
775
|
+
validate_committed_state = validate_committed_ge_beam3_mixed_state
|
|
776
|
+
serialize_committed_state = serialize_ge_beam3_mixed_state
|
|
777
|
+
deserialize_committed_state = deserialize_ge_beam3_mixed_state
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
__all__ = [
|
|
781
|
+
"COMMIT_STATUS",
|
|
782
|
+
"GE_BEAM3_MIXED_CANDIDATE_ID",
|
|
783
|
+
"GE_BEAM3_MIXED_FORMULATION_ID",
|
|
784
|
+
"GeBeam3MixedCommittedStateError",
|
|
785
|
+
"GeBeam3MixedStateContractError",
|
|
786
|
+
"LOCAL_STATE_ROLE",
|
|
787
|
+
"SECTION_SCHEMA",
|
|
788
|
+
"SECTION_STATE_MODE",
|
|
789
|
+
"SECTION_STATION_IDS",
|
|
790
|
+
"STATE_INTEGRITY_ID",
|
|
791
|
+
"STATE_LAYOUT_ID",
|
|
792
|
+
"STATE_SCHEMA",
|
|
793
|
+
"STATE_VERSION",
|
|
794
|
+
"build_committed_state",
|
|
795
|
+
"canonical_json_bytes",
|
|
796
|
+
"canonical_sha256",
|
|
797
|
+
"decode_typed_array",
|
|
798
|
+
"deserialize_committed_state",
|
|
799
|
+
"deserialize_ge_beam3_mixed_state",
|
|
800
|
+
"element_identity_payload",
|
|
801
|
+
"element_identity_sha256",
|
|
802
|
+
"encode_typed_array",
|
|
803
|
+
"initialize_ge_beam3_mixed_state",
|
|
804
|
+
"model_bound_identity",
|
|
805
|
+
"seal_committed_ge_beam3_mixed_state",
|
|
806
|
+
"seal_committed_state",
|
|
807
|
+
"section_descriptor_payload",
|
|
808
|
+
"section_descriptor_sha256",
|
|
809
|
+
"serialize_committed_state",
|
|
810
|
+
"serialize_ge_beam3_mixed_state",
|
|
811
|
+
"strict_canonical_json_loads",
|
|
812
|
+
"validate_committed_ge_beam3_mixed_state",
|
|
813
|
+
"validate_committed_state",
|
|
814
|
+
]
|