freedyn2 0.1.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- freedyn2-0.1.0rc1/.gitattributes +5 -0
- freedyn2-0.1.0rc1/.github/workflows/ci.yml +127 -0
- freedyn2-0.1.0rc1/.github/workflows/docs.yml +58 -0
- freedyn2-0.1.0rc1/.github/workflows/wheels.yml +340 -0
- freedyn2-0.1.0rc1/.gitignore +15 -0
- freedyn2-0.1.0rc1/CHANGELOG.md +36 -0
- freedyn2-0.1.0rc1/CITATION.cff +78 -0
- freedyn2-0.1.0rc1/CLAUDE.md +9 -0
- freedyn2-0.1.0rc1/CMakeLists.txt +198 -0
- freedyn2-0.1.0rc1/LICENSE +202 -0
- freedyn2-0.1.0rc1/NOTICE +24 -0
- freedyn2-0.1.0rc1/PKG-INFO +512 -0
- freedyn2-0.1.0rc1/README.md +483 -0
- freedyn2-0.1.0rc1/brand/README.md +74 -0
- freedyn2-0.1.0rc1/brand/logo/app-icon.svg +3 -0
- freedyn2-0.1.0rc1/brand/logo/avatar.svg +3 -0
- freedyn2-0.1.0rc1/brand/logo/favicon.svg +3 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-claim-dark.svg +39 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-claim-light.svg +39 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-dark-transparent.svg +13 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-dark.svg +13 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-light-transparent.svg +13 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-light.svg +13 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-small-dark.svg +12 -0
- freedyn2-0.1.0rc1/brand/logo/lockup-small-light.svg +12 -0
- freedyn2-0.1.0rc1/brand/logo/mark-dark.svg +3 -0
- freedyn2-0.1.0rc1/brand/logo/mark-light.svg +3 -0
- freedyn2-0.1.0rc1/brand/make_logos.py +180 -0
- freedyn2-0.1.0rc1/brand/tokens.css +54 -0
- freedyn2-0.1.0rc1/brand/tokens.json +59 -0
- freedyn2-0.1.0rc1/cmake/copy_dlls.cmake +5 -0
- freedyn2-0.1.0rc1/docs/architecture.md +456 -0
- freedyn2-0.1.0rc1/docs/assistants.md +96 -0
- freedyn2-0.1.0rc1/docs/cli.md +165 -0
- freedyn2-0.1.0rc1/docs/download.md +47 -0
- freedyn2-0.1.0rc1/docs/examples.md +81 -0
- freedyn2-0.1.0rc1/docs/extensions.md +217 -0
- freedyn2-0.1.0rc1/docs/findings.md +66 -0
- freedyn2-0.1.0rc1/docs/from-adams.md +75 -0
- freedyn2-0.1.0rc1/docs/from-freedyn.md +161 -0
- freedyn2-0.1.0rc1/docs/getting-started.md +183 -0
- freedyn2-0.1.0rc1/docs/how-it-works.md +337 -0
- freedyn2-0.1.0rc1/docs/img/app-start.png +0 -0
- freedyn2-0.1.0rc1/docs/img/car-crg.png +0 -0
- freedyn2-0.1.0rc1/docs/img/fan.png +0 -0
- freedyn2-0.1.0rc1/docs/img/pendulum.png +0 -0
- freedyn2-0.1.0rc1/docs/img/root-locus.png +0 -0
- freedyn2-0.1.0rc1/docs/img/runs-delta.png +0 -0
- freedyn2-0.1.0rc1/docs/img/runs-reference.png +0 -0
- freedyn2-0.1.0rc1/docs/img/tune-pending.png +0 -0
- freedyn2-0.1.0rc1/docs/img/viewer.png +0 -0
- freedyn2-0.1.0rc1/docs/index.md +57 -0
- freedyn2-0.1.0rc1/docs/javascripts/mathjax.js +5 -0
- freedyn2-0.1.0rc1/docs/privacy.md +29 -0
- freedyn2-0.1.0rc1/docs/python-api.md +118 -0
- freedyn2-0.1.0rc1/docs/reference/bodies.md +52 -0
- freedyn2-0.1.0rc1/docs/reference/checks.md +44 -0
- freedyn2-0.1.0rc1/docs/reference/forces.md +124 -0
- freedyn2-0.1.0rc1/docs/reference/hardpoints.md +98 -0
- freedyn2-0.1.0rc1/docs/reference/joints.md +43 -0
- freedyn2-0.1.0rc1/docs/reference/measures.md +105 -0
- freedyn2-0.1.0rc1/docs/reference/model-file.md +120 -0
- freedyn2-0.1.0rc1/docs/reference/results.md +56 -0
- freedyn2-0.1.0rc1/docs/reference/sensors.md +62 -0
- freedyn2-0.1.0rc1/docs/reference/solver.md +53 -0
- freedyn2-0.1.0rc1/docs/reference/tires-roads.md +67 -0
- freedyn2-0.1.0rc1/docs/releasing.md +210 -0
- freedyn2-0.1.0rc1/docs/stylesheets/extra.css +2 -0
- freedyn2-0.1.0rc1/docs/theory.md +721 -0
- freedyn2-0.1.0rc1/docs/tutorial-crg.md +164 -0
- freedyn2-0.1.0rc1/docs/tutorial.md +163 -0
- freedyn2-0.1.0rc1/docs/viewer.md +177 -0
- freedyn2-0.1.0rc1/examples/bushing_mount.yaml +14 -0
- freedyn2-0.1.0rc1/examples/car_on_crg.yaml +98 -0
- freedyn2-0.1.0rc1/examples/compare/data/stiff.txt +10 -0
- freedyn2-0.1.0rc1/examples/compare/double_pendulum.fds +96 -0
- freedyn2-0.1.0rc1/examples/compare/driven_base.fds +161 -0
- freedyn2-0.1.0rc1/examples/compare/driven_rotor.fds +140 -0
- freedyn2-0.1.0rc1/examples/compare/dzhanibekov.fds +46 -0
- freedyn2-0.1.0rc1/examples/compare/fast_rotor.fds +50 -0
- freedyn2-0.1.0rc1/examples/compare/fast_rotor_modified.fds +50 -0
- freedyn2-0.1.0rc1/examples/compare/forced_oscillator.fds +124 -0
- freedyn2-0.1.0rc1/examples/compare/free_body.fds +50 -0
- freedyn2-0.1.0rc1/examples/compare/pendulum.fds +73 -0
- freedyn2-0.1.0rc1/examples/compare/rotated_gui_defaults.fds +46 -0
- freedyn2-0.1.0rc1/examples/compare/spline_spring.fds +130 -0
- freedyn2-0.1.0rc1/examples/compare/spring_chain.fds +221 -0
- freedyn2-0.1.0rc1/examples/compare/step_control.fds +46 -0
- freedyn2-0.1.0rc1/examples/compare/torsion_disks.fds +183 -0
- freedyn2-0.1.0rc1/examples/constant_loads.yaml +11 -0
- freedyn2-0.1.0rc1/examples/data/make_test_track.py +58 -0
- freedyn2-0.1.0rc1/examples/data/spline_slider_law.txt +9 -0
- freedyn2-0.1.0rc1/examples/data/test_track.crg +0 -0
- freedyn2-0.1.0rc1/examples/double_pendulum.yaml +35 -0
- freedyn2-0.1.0rc1/examples/double_wishbone.yaml +93 -0
- freedyn2-0.1.0rc1/examples/driven_rotor.yaml +20 -0
- freedyn2-0.1.0rc1/examples/dzhanibekov.yaml +10 -0
- freedyn2-0.1.0rc1/examples/extension/freedyn2_drag/__init__.py +68 -0
- freedyn2-0.1.0rc1/examples/extension/pyproject.toml +17 -0
- freedyn2-0.1.0rc1/examples/forced_oscillator.yaml +19 -0
- freedyn2-0.1.0rc1/examples/free_body.yaml +12 -0
- freedyn2-0.1.0rc1/examples/input_oscillator.yaml +30 -0
- freedyn2-0.1.0rc1/examples/oscillator.yaml +16 -0
- freedyn2-0.1.0rc1/examples/pendulum.yaml +17 -0
- freedyn2-0.1.0rc1/examples/quarter_car.yaml +69 -0
- freedyn2-0.1.0rc1/examples/scaling/car_1.fds +928 -0
- freedyn2-0.1.0rc1/examples/scaling/make_car.py +218 -0
- freedyn2-0.1.0rc1/examples/scaling/scaling.py +64 -0
- freedyn2-0.1.0rc1/examples/spline_slider.yaml +15 -0
- freedyn2-0.1.0rc1/examples/spring_pendulum.yaml +14 -0
- freedyn2-0.1.0rc1/examples/torsion_pendulum.yaml +11 -0
- freedyn2-0.1.0rc1/examples/two_bodies.yaml +11 -0
- freedyn2-0.1.0rc1/examples/winding_spring.yaml +15 -0
- freedyn2-0.1.0rc1/generator/fdgen/__init__.py +23 -0
- freedyn2-0.1.0rc1/generator/fdgen/__main__.py +39 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/__init__.py +196 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/freedyn2.ico +0 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/freedyn2.png +0 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/freedyn2.svg +18 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/instance.py +72 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/native.py +111 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/recent.py +57 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/server.py +388 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/web/shell.js +51 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/web/start.html +137 -0
- freedyn2-0.1.0rc1/generator/fdgen/app/web/start.js +165 -0
- freedyn2-0.1.0rc1/generator/fdgen/checks.py +312 -0
- freedyn2-0.1.0rc1/generator/fdgen/cli.py +283 -0
- freedyn2-0.1.0rc1/generator/fdgen/codegen.py +133 -0
- freedyn2-0.1.0rc1/generator/fdgen/convert.py +475 -0
- freedyn2-0.1.0rc1/generator/fdgen/crg.py +82 -0
- freedyn2-0.1.0rc1/generator/fdgen/custom_element.py +152 -0
- freedyn2-0.1.0rc1/generator/fdgen/doctor.py +119 -0
- freedyn2-0.1.0rc1/generator/fdgen/drivers.py +49 -0
- freedyn2-0.1.0rc1/generator/fdgen/errors.py +17 -0
- freedyn2-0.1.0rc1/generator/fdgen/expression_forces.py +68 -0
- freedyn2-0.1.0rc1/generator/fdgen/expressions.py +105 -0
- freedyn2-0.1.0rc1/generator/fdgen/extensions.py +109 -0
- freedyn2-0.1.0rc1/generator/fdgen/fds/__init__.py +150 -0
- freedyn2-0.1.0rc1/generator/fdgen/fds/blocks.py +55 -0
- freedyn2-0.1.0rc1/generator/fdgen/fds/bodies.py +77 -0
- freedyn2-0.1.0rc1/generator/fdgen/fds/loads.py +231 -0
- freedyn2-0.1.0rc1/generator/fdgen/fds/solver.py +54 -0
- freedyn2-0.1.0rc1/generator/fdgen/forces.py +274 -0
- freedyn2-0.1.0rc1/generator/fdgen/formulas.py +98 -0
- freedyn2-0.1.0rc1/generator/fdgen/geometry.py +41 -0
- freedyn2-0.1.0rc1/generator/fdgen/hardpoints.py +222 -0
- freedyn2-0.1.0rc1/generator/fdgen/joints.py +105 -0
- freedyn2-0.1.0rc1/generator/fdgen/kinematics.py +176 -0
- freedyn2-0.1.0rc1/generator/fdgen/lagrange.py +280 -0
- freedyn2-0.1.0rc1/generator/fdgen/linearize.py +297 -0
- freedyn2-0.1.0rc1/generator/fdgen/mcp_server.py +502 -0
- freedyn2-0.1.0rc1/generator/fdgen/mcp_setup.py +208 -0
- freedyn2-0.1.0rc1/generator/fdgen/measures.py +167 -0
- freedyn2-0.1.0rc1/generator/fdgen/model.py +406 -0
- freedyn2-0.1.0rc1/generator/fdgen/msvc.py +125 -0
- freedyn2-0.1.0rc1/generator/fdgen/outputs.py +32 -0
- freedyn2-0.1.0rc1/generator/fdgen/plugin.py +276 -0
- freedyn2-0.1.0rc1/generator/fdgen/resources.py +17 -0
- freedyn2-0.1.0rc1/generator/fdgen/rigid_body.py +219 -0
- freedyn2-0.1.0rc1/generator/fdgen/shapes.py +104 -0
- freedyn2-0.1.0rc1/generator/fdgen/splines.py +141 -0
- freedyn2-0.1.0rc1/generator/fdgen/sweep.py +105 -0
- freedyn2-0.1.0rc1/generator/fdgen/tire.py +194 -0
- freedyn2-0.1.0rc1/generator/fdgen/update.py +180 -0
- freedyn2-0.1.0rc1/generator/fdgen/userdirs.py +81 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/__init__.py +1 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/notes.py +118 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/scene.py +268 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/server.py +608 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/channels.js +144 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/index.html +312 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/panels.js +510 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/plot.js +809 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/runs.js +79 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/LICENSE-three.js +21 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/OBJLoader.js +907 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/OrbitControls.js +1523 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/README.md +6 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/STLLoader.js +411 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/vendor/three.module.min.js +6 -0
- freedyn2-0.1.0rc1/generator/fdgen/view/web/viewer.js +1076 -0
- freedyn2-0.1.0rc1/generator/freedyn2/__init__.py +21 -0
- freedyn2-0.1.0rc1/generator/freedyn2/api.py +407 -0
- freedyn2-0.1.0rc1/installer/windows/THIRD-PARTY-NOTICES.txt +63 -0
- freedyn2-0.1.0rc1/installer/windows/build.py +460 -0
- freedyn2-0.1.0rc1/installer/windows/freedyn2-prompt.cmd +15 -0
- freedyn2-0.1.0rc1/installer/windows/freedyn2.iss +274 -0
- freedyn2-0.1.0rc1/installer/windows/signpath/installer.xml +14 -0
- freedyn2-0.1.0rc1/installer/windows/signpath/programs.xml +23 -0
- freedyn2-0.1.0rc1/installer/winget/FreeDynOrg.FreeDyn2.installer.yaml +36 -0
- freedyn2-0.1.0rc1/installer/winget/FreeDynOrg.FreeDyn2.locale.en-US.yaml +33 -0
- freedyn2-0.1.0rc1/installer/winget/FreeDynOrg.FreeDyn2.yaml +7 -0
- freedyn2-0.1.0rc1/installer/winget/render.py +42 -0
- freedyn2-0.1.0rc1/legacy/README.md +27 -0
- freedyn2-0.1.0rc1/legacy/benchmark.py +231 -0
- freedyn2-0.1.0rc1/legacy/build_legacy.py +233 -0
- freedyn2-0.1.0rc1/legacy/compare.py +258 -0
- freedyn2-0.1.0rc1/legacy/compat/Windows.h +36 -0
- freedyn2-0.1.0rc1/legacy/compat/concurrent_queue.h +26 -0
- freedyn2-0.1.0rc1/legacy/compat/io.h +2 -0
- freedyn2-0.1.0rc1/legacy/compat/legacy_compat.h +44 -0
- freedyn2-0.1.0rc1/legacy/compat/tbb/concurrent_vector.h +21 -0
- freedyn2-0.1.0rc1/legacy/compat/windows.h +36 -0
- freedyn2-0.1.0rc1/legacy/references/__init__.py +38 -0
- freedyn2-0.1.0rc1/legacy/references/common.py +42 -0
- freedyn2-0.1.0rc1/legacy/references/free_bodies.py +143 -0
- freedyn2-0.1.0rc1/legacy/references/free_body.py +55 -0
- freedyn2-0.1.0rc1/legacy/references/hinge_chain.py +93 -0
- freedyn2-0.1.0rc1/legacy/references/linear.py +55 -0
- freedyn2-0.1.0rc1/legacy/references/prescribed.py +126 -0
- freedyn2-0.1.0rc1/legacy/results.py +93 -0
- freedyn2-0.1.0rc1/mkdocs.yml +83 -0
- freedyn2-0.1.0rc1/pyproject.toml +69 -0
- freedyn2-0.1.0rc1/requirements-dev.txt +9 -0
- freedyn2-0.1.0rc1/requirements-docs.txt +2 -0
- freedyn2-0.1.0rc1/runtime/app/main.cpp +312 -0
- freedyn2-0.1.0rc1/runtime/app/road.cpp +84 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/crg.hpp +56 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/generated_function.hpp +45 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/hht.hpp +108 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/linear_solver.hpp +33 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/model.hpp +84 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/plugin.hpp +17 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/scatter.hpp +49 -0
- freedyn2-0.1.0rc1/runtime/include/freedyn2/system.hpp +141 -0
- freedyn2-0.1.0rc1/runtime/src/crg.cpp +112 -0
- freedyn2-0.1.0rc1/runtime/src/generated_function.cpp +50 -0
- freedyn2-0.1.0rc1/runtime/src/hht.cpp +364 -0
- freedyn2-0.1.0rc1/runtime/src/linear_solver.cpp +132 -0
- freedyn2-0.1.0rc1/runtime/src/model.cpp +170 -0
- freedyn2-0.1.0rc1/runtime/src/plugin.cpp +70 -0
- freedyn2-0.1.0rc1/runtime/src/scatter.cpp +62 -0
- freedyn2-0.1.0rc1/runtime/src/system.cpp +355 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/LICENSE +204 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/NOTICE +57 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/README.md +6 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/inc/crgBaseLib.h +611 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/inc/crgBaseLibPrivate.h +731 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgContactPoint.c +636 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgEvalpk.c +160 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgEvaluv2xy.c +203 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgEvalxy2uv.c +473 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgEvalz.c +679 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgLoader.c +3410 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgMgr.c +1014 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgMsg.c +94 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgOptionMgmt.c +575 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgPortability.c +169 -0
- freedyn2-0.1.0rc1/runtime/third_party/opencrg/src/crgStatistics.c +354 -0
- freedyn2-0.1.0rc1/schema/model.schema.json +358 -0
- freedyn2-0.1.0rc1/tests/cpp/CMakeLists.txt +22 -0
- freedyn2-0.1.0rc1/tests/cpp/force_tests.cpp +260 -0
- freedyn2-0.1.0rc1/tests/cpp/joint_tests.cpp +170 -0
- freedyn2-0.1.0rc1/tests/cpp/main.cpp +28 -0
- freedyn2-0.1.0rc1/tests/cpp/rigid_body_tests.cpp +448 -0
- freedyn2-0.1.0rc1/tests/cpp/test_support.cpp +122 -0
- freedyn2-0.1.0rc1/tests/cpp/test_support.hpp +60 -0
- freedyn2-0.1.0rc1/tests/python/conftest.py +75 -0
- freedyn2-0.1.0rc1/tests/python/test_api.py +132 -0
- freedyn2-0.1.0rc1/tests/python/test_app.py +447 -0
- freedyn2-0.1.0rc1/tests/python/test_checks.py +146 -0
- freedyn2-0.1.0rc1/tests/python/test_cli.py +205 -0
- freedyn2-0.1.0rc1/tests/python/test_codegen.py +76 -0
- freedyn2-0.1.0rc1/tests/python/test_convert.py +146 -0
- freedyn2-0.1.0rc1/tests/python/test_crg.py +193 -0
- freedyn2-0.1.0rc1/tests/python/test_custom_elements.py +413 -0
- freedyn2-0.1.0rc1/tests/python/test_docs.py +47 -0
- freedyn2-0.1.0rc1/tests/python/test_extension_example.py +108 -0
- freedyn2-0.1.0rc1/tests/python/test_fds.py +137 -0
- freedyn2-0.1.0rc1/tests/python/test_forces.py +179 -0
- freedyn2-0.1.0rc1/tests/python/test_formulas.py +79 -0
- freedyn2-0.1.0rc1/tests/python/test_hardpoints.py +160 -0
- freedyn2-0.1.0rc1/tests/python/test_joints.py +130 -0
- freedyn2-0.1.0rc1/tests/python/test_legacy_compare.py +55 -0
- freedyn2-0.1.0rc1/tests/python/test_legacy_physics.py +59 -0
- freedyn2-0.1.0rc1/tests/python/test_lie_group.py +123 -0
- freedyn2-0.1.0rc1/tests/python/test_linearize.py +54 -0
- freedyn2-0.1.0rc1/tests/python/test_mcp.py +148 -0
- freedyn2-0.1.0rc1/tests/python/test_rigid_body.py +121 -0
- freedyn2-0.1.0rc1/tests/python/test_schema.py +64 -0
- freedyn2-0.1.0rc1/tests/python/test_sensors.py +114 -0
- freedyn2-0.1.0rc1/tests/python/test_setup_tools.py +360 -0
- freedyn2-0.1.0rc1/tests/python/test_sweep.py +62 -0
- freedyn2-0.1.0rc1/tests/python/test_tire.py +72 -0
- freedyn2-0.1.0rc1/tests/python/test_view.py +505 -0
- freedyn2-0.1.0rc1/tools/build_deps.py +73 -0
- freedyn2-0.1.0rc1/tools/docs_examples.py +42 -0
- freedyn2-0.1.0rc1/tools/docs_hooks.py +78 -0
- freedyn2-0.1.0rc1/tools/make_app_icon.py +105 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main] # work branches run once, through their pull request
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
# a new push to a pull request cancels its runs still in progress
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build-and-test:
|
|
15
|
+
runs-on: ubuntu-24.04
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: |
|
|
23
|
+
sudo apt-get update
|
|
24
|
+
sudo apt-get install -y libeigen3-dev libsuitesparse-dev
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
python -m pip install -r requirements-dev.txt
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: python -m pyflakes generator legacy tests/python examples/extension tools installer
|
|
29
|
+
- name: Configure and build
|
|
30
|
+
run: |
|
|
31
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DPython3_EXECUTABLE="$(which python)"
|
|
32
|
+
cmake --build build -j
|
|
33
|
+
- name: C++ tests
|
|
34
|
+
run: ctest --test-dir build --output-on-failure -V
|
|
35
|
+
- name: Python tests (with the runtime built)
|
|
36
|
+
run: python -m pytest -v
|
|
37
|
+
- name: freedyn2 run (.fds and .yaml, model plugin)
|
|
38
|
+
env:
|
|
39
|
+
PYTHONPATH: generator
|
|
40
|
+
run: |
|
|
41
|
+
python -m fdgen.cli run examples/compare/pendulum.fds -o pendulum.csv
|
|
42
|
+
python -m fdgen.cli run examples/compare/spline_spring.fds -o spline_spring.csv
|
|
43
|
+
python -m fdgen.cli run examples/driven_rotor.yaml -o driven_rotor.csv -- --linear-solver klu
|
|
44
|
+
|
|
45
|
+
# Windows: MSVC; Eigen and KLU (SuiteSparse with only KLU and its parts, no BLAS, as DLLs:
|
|
46
|
+
# LGPL, linked dynamically) from tools/build_deps.py as for the wheels, cached; model plugins
|
|
47
|
+
# compiled with MSVC (CC=cl) as a user with Visual Studio Build Tools would.
|
|
48
|
+
windows:
|
|
49
|
+
runs-on: windows-latest
|
|
50
|
+
env:
|
|
51
|
+
CC: cl
|
|
52
|
+
PYTHONPATH: generator
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: actions/setup-python@v5
|
|
56
|
+
with:
|
|
57
|
+
python-version: "3.12"
|
|
58
|
+
- uses: ilammy/msvc-dev-cmd@v1
|
|
59
|
+
- uses: actions/cache@v4
|
|
60
|
+
with:
|
|
61
|
+
path: deps
|
|
62
|
+
key: deps-${{ runner.os }}-msvc-${{ hashFiles('tools/build_deps.py') }}
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: |
|
|
65
|
+
python -m pip install --upgrade pip
|
|
66
|
+
python -m pip install -r requirements-dev.txt
|
|
67
|
+
python tools/build_deps.py deps
|
|
68
|
+
- name: Configure and build
|
|
69
|
+
run: |
|
|
70
|
+
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$PWD\deps" `
|
|
71
|
+
-DPython3_EXECUTABLE="$((Get-Command python).Source)"
|
|
72
|
+
cmake --build build
|
|
73
|
+
- name: C++ tests
|
|
74
|
+
run: ctest --test-dir build --output-on-failure
|
|
75
|
+
- name: Python tests
|
|
76
|
+
run: python -m pytest -v
|
|
77
|
+
- name: freedyn2 run (.fds and .yaml, model plugin)
|
|
78
|
+
run: |
|
|
79
|
+
python -m fdgen.cli run examples/compare/pendulum.fds -o pendulum.csv
|
|
80
|
+
python -m fdgen.cli run examples/driven_rotor.yaml -o driven_rotor.csv -- --linear-solver klu
|
|
81
|
+
|
|
82
|
+
# FreeDyn 2 against the legacy kernel (freedyn-org/me, private). Needs a repository
|
|
83
|
+
# secret FREEDYN_ME_TOKEN with read access to freedyn-org/me; skipped without it.
|
|
84
|
+
legacy-compare:
|
|
85
|
+
runs-on: ubuntu-24.04
|
|
86
|
+
env:
|
|
87
|
+
HAS_TOKEN: ${{ secrets.FREEDYN_ME_TOKEN != '' }}
|
|
88
|
+
steps:
|
|
89
|
+
- name: Notice
|
|
90
|
+
if: env.HAS_TOKEN != 'true'
|
|
91
|
+
run: echo "::notice::FREEDYN_ME_TOKEN is not set, legacy comparison skipped"
|
|
92
|
+
- uses: actions/checkout@v4
|
|
93
|
+
if: env.HAS_TOKEN == 'true'
|
|
94
|
+
- uses: actions/checkout@v4
|
|
95
|
+
if: env.HAS_TOKEN == 'true'
|
|
96
|
+
with:
|
|
97
|
+
repository: freedyn-org/me
|
|
98
|
+
token: ${{ secrets.FREEDYN_ME_TOKEN }}
|
|
99
|
+
path: me
|
|
100
|
+
- uses: actions/setup-python@v5
|
|
101
|
+
if: env.HAS_TOKEN == 'true'
|
|
102
|
+
with:
|
|
103
|
+
python-version: "3.12"
|
|
104
|
+
- name: Install dependencies
|
|
105
|
+
if: env.HAS_TOKEN == 'true'
|
|
106
|
+
run: |
|
|
107
|
+
sudo apt-get update
|
|
108
|
+
sudo apt-get install -y libeigen3-dev libsuitesparse-dev
|
|
109
|
+
python -m pip install --upgrade pip
|
|
110
|
+
python -m pip install -r requirements-dev.txt mkl-devel
|
|
111
|
+
- name: Build FreeDyn 2
|
|
112
|
+
if: env.HAS_TOKEN == 'true'
|
|
113
|
+
run: |
|
|
114
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DPython3_EXECUTABLE="$(which python)"
|
|
115
|
+
cmake --build build -j
|
|
116
|
+
- name: Build legacy FreeDyn
|
|
117
|
+
if: env.HAS_TOKEN == 'true'
|
|
118
|
+
run: MKL_ROOT="$(python -c 'import sys; print(sys.prefix)')" python legacy/build_legacy.py me -o build/legacy
|
|
119
|
+
- name: Compare
|
|
120
|
+
if: env.HAS_TOKEN == 'true'
|
|
121
|
+
run: |
|
|
122
|
+
python -m pytest -v tests/python/test_legacy_compare.py tests/python/test_legacy_physics.py
|
|
123
|
+
python legacy/compare.py examples/compare/*.fds --level exact --markdown exact.md
|
|
124
|
+
python legacy/compare.py examples/compare/*.fds --level physics --markdown physics.md
|
|
125
|
+
PYTHONPATH=generator python -m fdgen.cli compare examples/compare/*.fds --legacy build/legacy/build/FreeDyn --markdown demo.md
|
|
126
|
+
{ echo "### freedyn2 compare (both programs on the same .fds, converged reference)"; cat demo.md; echo
|
|
127
|
+
echo "### Exact (legacy profile)"; cat exact.md; echo; echo "### Physics (v2 profile vs reference)"; cat physics.md; } >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
# The user documentation (mkdocs.yml, docs/) with the live examples (tools/docs_examples.py:
|
|
4
|
+
# viewers exported with the runtime). Built on every pull request that touches it; published
|
|
5
|
+
# to GitHub Pages from main once Pages is enabled (Settings → Pages → Source: GitHub Actions,
|
|
6
|
+
# and the repository variable PAGES_ENABLED = true).
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches: [main]
|
|
11
|
+
pull_request:
|
|
12
|
+
paths: [docs/**, mkdocs.yml, tools/docs_*.py, examples/**, schema/**, generator/fdgen/view/**, .github/workflows/docs.yml]
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: docs-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
build:
|
|
21
|
+
runs-on: ubuntu-24.04
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
sudo apt-get update
|
|
30
|
+
sudo apt-get install -y libeigen3-dev libsuitesparse-dev
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python -m pip install -r requirements-dev.txt -r requirements-docs.txt
|
|
33
|
+
- name: Build the runtime
|
|
34
|
+
run: |
|
|
35
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DFD_BUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DPython3_EXECUTABLE="$(which python)"
|
|
36
|
+
cmake --build build -j --target freedyn2_run freedyn2_road
|
|
37
|
+
- name: Live examples
|
|
38
|
+
run: python tools/docs_examples.py
|
|
39
|
+
- name: Build the site
|
|
40
|
+
run: mkdocs build --strict
|
|
41
|
+
- uses: actions/upload-pages-artifact@v3
|
|
42
|
+
if: github.ref == 'refs/heads/main' && vars.PAGES_ENABLED == 'true'
|
|
43
|
+
with:
|
|
44
|
+
path: site
|
|
45
|
+
|
|
46
|
+
deploy:
|
|
47
|
+
needs: build
|
|
48
|
+
if: github.ref == 'refs/heads/main' && vars.PAGES_ENABLED == 'true'
|
|
49
|
+
runs-on: ubuntu-24.04
|
|
50
|
+
permissions:
|
|
51
|
+
pages: write
|
|
52
|
+
id-token: write
|
|
53
|
+
environment:
|
|
54
|
+
name: github-pages
|
|
55
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
56
|
+
steps:
|
|
57
|
+
- id: deployment
|
|
58
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
name: Wheels
|
|
2
|
+
|
|
3
|
+
# Wheels for Windows and Linux (pip install / uv tool install freedyn2): the Python package with
|
|
4
|
+
# the compiled runtime and its KLU libraries (pyproject.toml: scikit-build-core, cibuildwheel), and
|
|
5
|
+
# the Windows installer built from the Windows wheel (installer/windows).
|
|
6
|
+
# Runs for pull requests that change the packaging, by hand, and for version tags. A version tag
|
|
7
|
+
# (v0.1.0, ...) must equal the version in pyproject.toml; it publishes to PyPI (trusted publishing:
|
|
8
|
+
# the PyPI project must have this repository and workflow registered as a trusted publisher,
|
|
9
|
+
# environment "pypi"), creates the GitHub Release with the wheels, the sdist and the installer,
|
|
10
|
+
# and updates the winget package (secret WINGET_TOKEN). Maintainers: docs/releasing.md.
|
|
11
|
+
#
|
|
12
|
+
# Code signing (optional, on version tags only): SignPath (SignPath Foundation for open-source
|
|
13
|
+
# projects), enabled by the secret SIGNPATH_API_TOKEN and the variables SIGNPATH_ORGANIZATION_ID,
|
|
14
|
+
# SIGNPATH_PROJECT_SLUG, SIGNPATH_SIGNING_POLICY_SLUG, SIGNPATH_CONFIG_PROGRAMS,
|
|
15
|
+
# SIGNPATH_CONFIG_INSTALLER (artifact configurations: installer/windows/signpath). Without the token
|
|
16
|
+
# the installer is built unsigned. Another signer replaces the two steps "Sign the programs" and
|
|
17
|
+
# "Sign the installer": they read build/installer/to-sign and dist-installer and write the signed
|
|
18
|
+
# files back to the same places.
|
|
19
|
+
on:
|
|
20
|
+
pull_request:
|
|
21
|
+
paths: [pyproject.toml, CMakeLists.txt, tools/**, installer/**, .github/workflows/wheels.yml]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
push:
|
|
24
|
+
tags: ["v*"]
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: wheels-${{ github.ref }}
|
|
28
|
+
cancel-in-progress: true
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
version:
|
|
32
|
+
runs-on: ubuntu-24.04
|
|
33
|
+
outputs:
|
|
34
|
+
version: ${{ steps.v.outputs.version }}
|
|
35
|
+
prerelease: ${{ steps.v.outputs.prerelease }}
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- name: Version of pyproject.toml (equal to the tag for a release)
|
|
39
|
+
id: v
|
|
40
|
+
run: |
|
|
41
|
+
v=$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
|
|
42
|
+
echo "version=$v" >> "$GITHUB_OUTPUT"
|
|
43
|
+
if [[ "$v" =~ [a-zA-Z] ]]; then echo "prerelease=true" >> "$GITHUB_OUTPUT"; else echo "prerelease=false" >> "$GITHUB_OUTPUT"; fi
|
|
44
|
+
if [[ "$GITHUB_REF" == refs/tags/v* && "${GITHUB_REF_NAME#v}" != "$v" ]]; then
|
|
45
|
+
echo "::error::tag $GITHUB_REF_NAME does not match the version $v in pyproject.toml (expected tag v$v)"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
echo "version $v"
|
|
49
|
+
|
|
50
|
+
wheels:
|
|
51
|
+
needs: [version]
|
|
52
|
+
strategy:
|
|
53
|
+
matrix:
|
|
54
|
+
os: [ubuntu-24.04, windows-latest]
|
|
55
|
+
runs-on: ${{ matrix.os }}
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- uses: actions/cache@v4 # the dependencies of the Windows build (on Linux they are built in the container)
|
|
59
|
+
if: runner.os == 'Windows'
|
|
60
|
+
with:
|
|
61
|
+
path: C:/fd-deps
|
|
62
|
+
key: wheel-deps-${{ runner.os }}-${{ hashFiles('tools/build_deps.py') }}
|
|
63
|
+
- uses: pypa/cibuildwheel@v2.23.3
|
|
64
|
+
env:
|
|
65
|
+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
|
|
66
|
+
- uses: actions/upload-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: wheels-${{ matrix.os }}
|
|
69
|
+
path: wheelhouse/*.whl
|
|
70
|
+
|
|
71
|
+
sdist:
|
|
72
|
+
needs: [version]
|
|
73
|
+
runs-on: ubuntu-24.04
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@v4
|
|
76
|
+
- run: pipx run build --sdist
|
|
77
|
+
- uses: actions/upload-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: sdist
|
|
80
|
+
path: dist/*.tar.gz
|
|
81
|
+
|
|
82
|
+
# The Windows installer (Inno Setup) from the Windows wheel, then installed, used and uninstalled.
|
|
83
|
+
installer:
|
|
84
|
+
needs: [wheels]
|
|
85
|
+
runs-on: windows-latest
|
|
86
|
+
env:
|
|
87
|
+
SIGNER: ${{ (secrets.SIGNPATH_API_TOKEN != '' && startsWith(github.ref, 'refs/tags/v')) && 'signpath' || 'none' }}
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v4
|
|
90
|
+
- uses: actions/setup-python@v5
|
|
91
|
+
with:
|
|
92
|
+
python-version: "3.12"
|
|
93
|
+
- uses: actions/download-artifact@v4
|
|
94
|
+
with:
|
|
95
|
+
name: wheels-windows-latest
|
|
96
|
+
path: wheelhouse
|
|
97
|
+
- name: Inno Setup
|
|
98
|
+
run: |
|
|
99
|
+
$iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe"
|
|
100
|
+
if (-not (Test-Path $iscc)) {
|
|
101
|
+
choco install innosetup -y --no-progress
|
|
102
|
+
if ($LASTEXITCODE) { exit 1 }
|
|
103
|
+
}
|
|
104
|
+
if (-not (Test-Path $iscc)) { Write-Error "ISCC.exe not found after installing Inno Setup"; exit 1 }
|
|
105
|
+
"ISCC=$iscc" >> $env:GITHUB_ENV
|
|
106
|
+
- uses: actions/cache@v4
|
|
107
|
+
with:
|
|
108
|
+
path: build/installer/downloads
|
|
109
|
+
key: installer-python-${{ hashFiles('installer/windows/build.py') }}
|
|
110
|
+
- name: Stage (Python, packages, launchers)
|
|
111
|
+
run: python installer/windows/build.py stage --wheel-dir wheelhouse --work build/installer
|
|
112
|
+
|
|
113
|
+
# --- signing of the programs inside the installer (SIGNER) -----------------------------
|
|
114
|
+
- name: Collect the programs to sign
|
|
115
|
+
if: env.SIGNER != 'none'
|
|
116
|
+
run: |
|
|
117
|
+
# our own programs only (python.exe and the packages' binaries carry their makers' signatures)
|
|
118
|
+
$stage = "build/installer/stage/core"
|
|
119
|
+
$files = @(Get-ChildItem "$stage/bin/*.exe") + @(Get-ChildItem "$stage/python/Scripts/freedyn2*.exe") +
|
|
120
|
+
@(Get-ChildItem "$stage/python/Lib/site-packages/fdgen/bin/*.exe")
|
|
121
|
+
foreach ($f in $files) {
|
|
122
|
+
$rel = [IO.Path]::GetRelativePath((Resolve-Path $stage), $f.FullName)
|
|
123
|
+
$dest = Join-Path "build/installer/to-sign" $rel
|
|
124
|
+
New-Item -ItemType Directory -Force (Split-Path $dest) | Out-Null
|
|
125
|
+
Copy-Item $f.FullName $dest
|
|
126
|
+
}
|
|
127
|
+
Get-ChildItem -Recurse -File build/installer/to-sign | ForEach-Object FullName
|
|
128
|
+
- name: Upload the programs to sign
|
|
129
|
+
if: env.SIGNER == 'signpath'
|
|
130
|
+
id: upload-programs
|
|
131
|
+
uses: actions/upload-artifact@v4
|
|
132
|
+
with:
|
|
133
|
+
name: programs-unsigned
|
|
134
|
+
path: build/installer/to-sign
|
|
135
|
+
- name: Sign the programs
|
|
136
|
+
if: env.SIGNER == 'signpath'
|
|
137
|
+
uses: signpath/github-action-submit-signing-request@f6d04783b4569d051e0c80105fe66e82819d0092 # v3.0
|
|
138
|
+
with:
|
|
139
|
+
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
|
140
|
+
organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
|
|
141
|
+
project-slug: ${{ vars.SIGNPATH_PROJECT_SLUG }}
|
|
142
|
+
signing-policy-slug: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
|
|
143
|
+
artifact-configuration-slug: ${{ vars.SIGNPATH_CONFIG_PROGRAMS }}
|
|
144
|
+
github-artifact-id: ${{ steps.upload-programs.outputs.artifact-id }}
|
|
145
|
+
wait-for-completion: true
|
|
146
|
+
wait-for-completion-timeout-in-seconds: 7200 # release signing waits for a manual approval
|
|
147
|
+
output-artifact-directory: build/installer/to-sign
|
|
148
|
+
- name: Put the signed programs into the stage
|
|
149
|
+
if: env.SIGNER != 'none'
|
|
150
|
+
run: |
|
|
151
|
+
Copy-Item -Recurse -Force build/installer/to-sign/* build/installer/stage/core/
|
|
152
|
+
Get-ChildItem -Recurse -File build/installer/to-sign | ForEach-Object {
|
|
153
|
+
$s = Get-AuthenticodeSignature $_.FullName
|
|
154
|
+
"$($s.Status) $($_.Name)"
|
|
155
|
+
if ($s.Status -ne 'Valid') { Write-Error "$($_.Name) is not signed"; exit 1 }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- name: Installer
|
|
159
|
+
run: python installer/windows/build.py compile --work build/installer --out dist-installer --iscc "$env:ISCC"
|
|
160
|
+
|
|
161
|
+
- name: Upload the installer to sign
|
|
162
|
+
if: env.SIGNER == 'signpath'
|
|
163
|
+
id: upload-installer
|
|
164
|
+
uses: actions/upload-artifact@v4
|
|
165
|
+
with:
|
|
166
|
+
name: installer-unsigned
|
|
167
|
+
path: dist-installer/*.exe
|
|
168
|
+
- name: Sign the installer
|
|
169
|
+
if: env.SIGNER == 'signpath'
|
|
170
|
+
uses: signpath/github-action-submit-signing-request@f6d04783b4569d051e0c80105fe66e82819d0092 # v3.0
|
|
171
|
+
with:
|
|
172
|
+
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
|
173
|
+
organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
|
|
174
|
+
project-slug: ${{ vars.SIGNPATH_PROJECT_SLUG }}
|
|
175
|
+
signing-policy-slug: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
|
|
176
|
+
artifact-configuration-slug: ${{ vars.SIGNPATH_CONFIG_INSTALLER }}
|
|
177
|
+
github-artifact-id: ${{ steps.upload-installer.outputs.artifact-id }}
|
|
178
|
+
wait-for-completion: true
|
|
179
|
+
wait-for-completion-timeout-in-seconds: 7200
|
|
180
|
+
output-artifact-directory: dist-installer
|
|
181
|
+
- name: Check the signature of the installer
|
|
182
|
+
if: env.SIGNER != 'none'
|
|
183
|
+
run: |
|
|
184
|
+
$s = Get-AuthenticodeSignature (Get-ChildItem dist-installer/FreeDyn2-*-setup.exe)
|
|
185
|
+
"$($s.Status) $($s.SignerCertificate.Subject)"
|
|
186
|
+
if ($s.Status -ne 'Valid') { exit 1 }
|
|
187
|
+
|
|
188
|
+
# --- smoke test: install silently (per user, into a path with a space), use, uninstall ----
|
|
189
|
+
- name: Smoke test
|
|
190
|
+
run: |
|
|
191
|
+
$ErrorActionPreference = 'Stop'
|
|
192
|
+
function Check([string]$what) { if ($LASTEXITCODE) { Write-Error "$what failed (exit code $LASTEXITCODE)" } }
|
|
193
|
+
$setup = (Get-ChildItem dist-installer/FreeDyn2-*-setup.exe | Select-Object -First 1).FullName
|
|
194
|
+
$dir = Join-Path $env:RUNNER_TEMP 'FreeDyn2 smoke'
|
|
195
|
+
$log = Join-Path $env:RUNNER_TEMP 'install.log'
|
|
196
|
+
$p = Start-Process $setup -Wait -PassThru -ArgumentList '/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', '/CURRENTUSER',
|
|
197
|
+
"/DIR=`"$dir`"", '/COMPONENTS=core,compiler,examples', '/TASKS=path', "/LOG=`"$log`""
|
|
198
|
+
if ($p.ExitCode -ne 0) { Get-Content $log -Tail 50; Write-Error "setup exit code $($p.ExitCode)" }
|
|
199
|
+
$bin = Join-Path $dir 'bin'
|
|
200
|
+
foreach ($f in 'bin\freedyn2.exe', 'bin\freedyn2-gui.exe', 'bin\freedyn2-prompt.cmd', 'python\python.exe',
|
|
201
|
+
'python\Lib\site-packages\ziglang', 'examples\driven_rotor.yaml', 'licenses\python-packages.txt',
|
|
202
|
+
'THIRD-PARTY-NOTICES.txt', 'unins000.exe') {
|
|
203
|
+
if (-not (Test-Path (Join-Path $dir $f))) { Write-Error "not installed: $f" }
|
|
204
|
+
}
|
|
205
|
+
$userPath = (Get-ItemProperty HKCU:\Environment).Path -split ';'
|
|
206
|
+
if ($userPath -notcontains $bin) { Write-Error "bin not on the user PATH: $userPath" }
|
|
207
|
+
|
|
208
|
+
# an isolated user: settings in FREEDYN2_HOME, no CC; the compiler is Zig (component compiler)
|
|
209
|
+
$env:FREEDYN2_HOME = Join-Path $env:RUNNER_TEMP 'fd2home'
|
|
210
|
+
Remove-Item Env:CC -ErrorAction SilentlyContinue
|
|
211
|
+
$work = Join-Path $env:RUNNER_TEMP 'fd2work'
|
|
212
|
+
New-Item -ItemType Directory -Force $work | Out-Null
|
|
213
|
+
Set-Location $work
|
|
214
|
+
$fd = Join-Path $bin 'freedyn2.exe'
|
|
215
|
+
& $fd --version; Check 'freedyn2 --version'
|
|
216
|
+
& $fd config compiler zig; Check 'freedyn2 config compiler zig'
|
|
217
|
+
& $fd doctor; Check 'freedyn2 doctor'
|
|
218
|
+
& $fd run (Join-Path $dir 'examples\compare\pendulum.fds') -o pendulum.csv; Check 'freedyn2 run pendulum.fds'
|
|
219
|
+
& $fd run (Join-Path $dir 'examples\driven_rotor.yaml') -o driven_rotor.csv; Check 'freedyn2 run driven_rotor.yaml (Zig)'
|
|
220
|
+
foreach ($csv in 'pendulum.csv', 'driven_rotor.csv') { if (-not (Test-Path $csv)) { Write-Error "no $csv" } }
|
|
221
|
+
& $fd setup-mcp --client claude-desktop --dry-run; Check 'freedyn2 setup-mcp --dry-run'
|
|
222
|
+
# the launcher in python\Scripts works as well (relocated like bin)
|
|
223
|
+
& (Join-Path $dir 'python\Scripts\freedyn2.exe') --version; Check 'python\Scripts\freedyn2.exe --version'
|
|
224
|
+
|
|
225
|
+
Set-Location $env:RUNNER_TEMP
|
|
226
|
+
$p = Start-Process (Join-Path $dir 'unins000.exe') -Wait -PassThru -ArgumentList '/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART'
|
|
227
|
+
if ($p.ExitCode -ne 0) { Write-Error "uninstall exit code $($p.ExitCode)" }
|
|
228
|
+
# the uninstaller continues from a copy in %TEMP%: wait for it
|
|
229
|
+
for ($i = 0; $i -lt 180 -and (Test-Path $dir); $i++) { Start-Sleep -Seconds 1 }
|
|
230
|
+
if (Test-Path $dir) { Get-ChildItem -Recurse $dir | Select-Object -First 30 | ForEach-Object FullName; Write-Error "left after uninstall: $dir" }
|
|
231
|
+
$userPath = (Get-ItemProperty HKCU:\Environment).Path -split ';'
|
|
232
|
+
if ($userPath -contains $bin) { Write-Error "bin still on the user PATH" }
|
|
233
|
+
"installed, used and uninstalled"
|
|
234
|
+
- uses: actions/upload-artifact@v4
|
|
235
|
+
with:
|
|
236
|
+
name: installer-windows
|
|
237
|
+
path: dist-installer/FreeDyn2-*-setup.exe
|
|
238
|
+
if-no-files-found: error
|
|
239
|
+
|
|
240
|
+
publish:
|
|
241
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
242
|
+
needs: [wheels, sdist, installer]
|
|
243
|
+
runs-on: ubuntu-24.04
|
|
244
|
+
environment: pypi
|
|
245
|
+
permissions:
|
|
246
|
+
id-token: write
|
|
247
|
+
steps:
|
|
248
|
+
- uses: actions/download-artifact@v4
|
|
249
|
+
with:
|
|
250
|
+
pattern: wheels-*
|
|
251
|
+
path: dist
|
|
252
|
+
merge-multiple: true
|
|
253
|
+
- uses: actions/download-artifact@v4
|
|
254
|
+
with:
|
|
255
|
+
name: sdist
|
|
256
|
+
path: dist
|
|
257
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
258
|
+
|
|
259
|
+
# GitHub Release vX.Y.Z: wheels, sdist, the installer (also as FreeDyn2-setup.exe for the stable
|
|
260
|
+
# link .../releases/latest/download/FreeDyn2-setup.exe), SHA256SUMS; notes from CHANGELOG.md
|
|
261
|
+
# and generated. The app's update notice reads the latest release.
|
|
262
|
+
release:
|
|
263
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
264
|
+
needs: [version, wheels, sdist, installer]
|
|
265
|
+
runs-on: ubuntu-24.04
|
|
266
|
+
permissions:
|
|
267
|
+
contents: write
|
|
268
|
+
steps:
|
|
269
|
+
- uses: actions/checkout@v4
|
|
270
|
+
- uses: actions/download-artifact@v4 # not the unsigned intermediates of the signing
|
|
271
|
+
with:
|
|
272
|
+
pattern: wheels-*
|
|
273
|
+
path: dist
|
|
274
|
+
merge-multiple: true
|
|
275
|
+
- uses: actions/download-artifact@v4
|
|
276
|
+
with:
|
|
277
|
+
name: sdist
|
|
278
|
+
path: dist
|
|
279
|
+
- uses: actions/download-artifact@v4
|
|
280
|
+
with:
|
|
281
|
+
name: installer-windows
|
|
282
|
+
path: dist
|
|
283
|
+
- name: Assets and notes
|
|
284
|
+
env:
|
|
285
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
286
|
+
run: |
|
|
287
|
+
cd dist
|
|
288
|
+
cp "FreeDyn2-$VERSION-setup.exe" FreeDyn2-setup.exe
|
|
289
|
+
sha256sum -- *.whl *.tar.gz *.exe > SHA256SUMS
|
|
290
|
+
cat SHA256SUMS
|
|
291
|
+
cd ..
|
|
292
|
+
# the section "## [VERSION]" of CHANGELOG.md (empty if there is none)
|
|
293
|
+
python3 - "$VERSION" > notes.md <<'EOF'
|
|
294
|
+
import re, sys
|
|
295
|
+
text = open("CHANGELOG.md", encoding="utf-8").read()
|
|
296
|
+
m = re.search(rf"^## \[{re.escape(sys.argv[1])}\][^\n]*\n(.*?)(?=^## |\Z)", text, re.M | re.S)
|
|
297
|
+
print(m.group(1).strip() if m else "")
|
|
298
|
+
EOF
|
|
299
|
+
cat notes.md
|
|
300
|
+
- uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
|
|
301
|
+
with:
|
|
302
|
+
name: FreeDyn 2 version ${{ needs.version.outputs.version }}
|
|
303
|
+
body_path: notes.md
|
|
304
|
+
generate_release_notes: true
|
|
305
|
+
prerelease: ${{ needs.version.outputs.prerelease == 'true' }}
|
|
306
|
+
make_latest: ${{ needs.version.outputs.prerelease == 'true' && 'false' || 'true' }}
|
|
307
|
+
fail_on_unmatched_files: true
|
|
308
|
+
files: |
|
|
309
|
+
dist/*.whl
|
|
310
|
+
dist/*.tar.gz
|
|
311
|
+
dist/FreeDyn2-*-setup.exe
|
|
312
|
+
dist/FreeDyn2-setup.exe
|
|
313
|
+
dist/SHA256SUMS
|
|
314
|
+
|
|
315
|
+
# winget (microsoft/winget-pkgs): a pull request with the new version, after the first version was
|
|
316
|
+
# submitted by hand (installer/winget). Needs the secret WINGET_TOKEN (a classic GitHub token
|
|
317
|
+
# with public_repo of an account with a fork of winget-pkgs); skipped without it and for pre-releases.
|
|
318
|
+
winget:
|
|
319
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
320
|
+
needs: [version, release]
|
|
321
|
+
runs-on: windows-latest
|
|
322
|
+
env:
|
|
323
|
+
HAS_TOKEN: ${{ secrets.WINGET_TOKEN != '' }}
|
|
324
|
+
PRERELEASE: ${{ needs.version.outputs.prerelease }}
|
|
325
|
+
steps:
|
|
326
|
+
- name: Notice
|
|
327
|
+
if: env.HAS_TOKEN != 'true' || env.PRERELEASE == 'true'
|
|
328
|
+
run: echo "::notice::winget update skipped (no WINGET_TOKEN, or a pre-release)"
|
|
329
|
+
- name: wingetcreate update
|
|
330
|
+
if: env.HAS_TOKEN == 'true' && env.PRERELEASE != 'true'
|
|
331
|
+
env:
|
|
332
|
+
WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }}
|
|
333
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
334
|
+
run: |
|
|
335
|
+
$url = "https://github.com/$env:GITHUB_REPOSITORY/releases/download/v$env:VERSION/FreeDyn2-$env:VERSION-setup.exe"
|
|
336
|
+
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
|
337
|
+
# the same installer for both scopes of the manifest (user, machine)
|
|
338
|
+
.\wingetcreate.exe update FreeDynOrg.FreeDyn2 --version $env:VERSION `
|
|
339
|
+
--urls "$url|x64|user" "$url|x64|machine" --submit --token $env:WINGET_TOKEN
|
|
340
|
+
if ($LASTEXITCODE) { exit 1 }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
build/
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.egg-info/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
*.csv
|
|
6
|
+
|
|
7
|
+
# tire data sets (.tir) stay outside the repository (FREEDYN2_TIR)
|
|
8
|
+
*.tir
|
|
9
|
+
|
|
10
|
+
# documentation: generated live examples, the built site
|
|
11
|
+
docs/live/
|
|
12
|
+
site/
|
|
13
|
+
|
|
14
|
+
# worktrees of parallel agent sessions
|
|
15
|
+
.claude/worktrees/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes of FreeDyn 2. Versions follow [semantic versioning](https://semver.org);
|
|
4
|
+
the section of a version becomes the text of its GitHub Release (docs/releasing.md).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.1.0rc1] - 2026-11-06
|
|
9
|
+
|
|
10
|
+
Release candidate: a test of the release process (PyPI, GitHub Release, Windows installer).
|
|
11
|
+
Not signed yet. Install it explicitly: `pip install --pre freedyn2` or the installer from this
|
|
12
|
+
release.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Wheels for Windows (x64) and Linux (x86_64): `pip install freedyn2`, `uv tool install freedyn2`;
|
|
17
|
+
extras `gui` (app window, pywebview) and `compiler` (Zig, a C compiler for model plugins).
|
|
18
|
+
- Windows installer `FreeDyn2-setup.exe`: per user without administrator rights, its own Python,
|
|
19
|
+
the app, the command line, optionally Zig, the .fds association and the Claude Desktop setup.
|
|
20
|
+
- The app `freedyn2-gui` / `freedyn2 gui`: start page (open, recent models, examples), a window
|
|
21
|
+
per model, one instance, an update notice for new releases.
|
|
22
|
+
- `freedyn2 convert`: legacy .fds models as YAML model files.
|
|
23
|
+
- The Python API: `import freedyn2` (load, run, check, sweep, convert).
|
|
24
|
+
- `freedyn2 setup-mcp`, `freedyn2 doctor`, `freedyn2 config`, `freedyn2 update-check`.
|
|
25
|
+
- Compiler selection: Zig, MSVC without a developer prompt (vswhere), gcc, clang.
|
|
26
|
+
|
|
27
|
+
## [0.1.0] - unreleased
|
|
28
|
+
|
|
29
|
+
First release.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- Wheels for Windows (x64) and Linux (x86_64) on PyPI: `pip install freedyn2`, `uv tool install freedyn2`.
|
|
34
|
+
- Windows installer `FreeDyn2-setup.exe` (per user, no administrator rights): its own Python, the
|
|
35
|
+
app, the viewer, the MCP server and optionally a C compiler (Zig) for model plugins.
|
|
36
|
+
- ...
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use FreeDyn 2, please cite it with these metadata."
|
|
3
|
+
title: "FreeDyn 2: multibody dynamics with generated models"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Oberpeilsteiner
|
|
7
|
+
given-names: Stefan
|
|
8
|
+
- name: "The FreeDyn 2 contributors"
|
|
9
|
+
repository-code: "https://github.com/freedyn-org/freedyn2"
|
|
10
|
+
url: "https://freedyn-org.github.io/freedyn2/"
|
|
11
|
+
license: Apache-2.0
|
|
12
|
+
keywords:
|
|
13
|
+
- multibody dynamics
|
|
14
|
+
- HHT
|
|
15
|
+
- Lie group time integration
|
|
16
|
+
- CasADi
|
|
17
|
+
- code generation
|
|
18
|
+
references:
|
|
19
|
+
- type: conference-paper
|
|
20
|
+
title: "FreeDyn: a free, flexible and state of the art multibody simulation package for education, research and industrial applications"
|
|
21
|
+
authors:
|
|
22
|
+
- family-names: Witteveen
|
|
23
|
+
given-names: Wolfgang
|
|
24
|
+
- family-names: Lauss
|
|
25
|
+
given-names: Thomas
|
|
26
|
+
- family-names: Oberpeilsteiner
|
|
27
|
+
given-names: Stefan
|
|
28
|
+
collection-title: "Nonlinear Structures & Systems, Volume 1"
|
|
29
|
+
publisher:
|
|
30
|
+
name: Springer
|
|
31
|
+
year: 2021
|
|
32
|
+
doi: "10.1007/978-3-030-47626-7_8"
|
|
33
|
+
- type: conference-paper
|
|
34
|
+
title: "FreeDyn: a multibody simulation research code"
|
|
35
|
+
authors:
|
|
36
|
+
- family-names: Nachbagauer
|
|
37
|
+
given-names: Karin
|
|
38
|
+
- family-names: Sherif
|
|
39
|
+
given-names: Karim
|
|
40
|
+
- family-names: Witteveen
|
|
41
|
+
given-names: Wolfgang
|
|
42
|
+
conference:
|
|
43
|
+
name: "11th World Congress on Computational Mechanics (WCCM XI), 5th European Conference on Computational Mechanics (ECCM V)"
|
|
44
|
+
city: Barcelona
|
|
45
|
+
year: 2014
|
|
46
|
+
- type: conference-paper
|
|
47
|
+
title: "FreeDyn: a software for advanced multibody simulation: applications in the field of vehicle dynamics"
|
|
48
|
+
authors:
|
|
49
|
+
- family-names: Oberpeilsteiner
|
|
50
|
+
given-names: Stefan
|
|
51
|
+
- family-names: Lauss
|
|
52
|
+
given-names: Thomas
|
|
53
|
+
- family-names: Eichmeir
|
|
54
|
+
given-names: Philipp
|
|
55
|
+
- family-names: Steiner
|
|
56
|
+
given-names: Wolfgang
|
|
57
|
+
conference:
|
|
58
|
+
name: "ECCOMAS Thematic Conference on Multibody Dynamics 2019"
|
|
59
|
+
city: Duisburg
|
|
60
|
+
year: 2019
|
|
61
|
+
- type: article
|
|
62
|
+
title: "A modified HHT method for the numerical simulation of rigid body rotations with Euler parameters"
|
|
63
|
+
authors:
|
|
64
|
+
- family-names: Sherif
|
|
65
|
+
given-names: Karim
|
|
66
|
+
- family-names: Nachbagauer
|
|
67
|
+
given-names: Karin
|
|
68
|
+
- family-names: Steiner
|
|
69
|
+
given-names: Wolfgang
|
|
70
|
+
- family-names: Lauss
|
|
71
|
+
given-names: Thomas
|
|
72
|
+
journal: "Multibody System Dynamics"
|
|
73
|
+
volume: 46
|
|
74
|
+
issue: 2
|
|
75
|
+
start: 181
|
|
76
|
+
end: 202
|
|
77
|
+
year: 2019
|
|
78
|
+
doi: "10.1007/s11044-019-09672-6"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Notes for Claude
|
|
2
|
+
|
|
3
|
+
## Brand
|
|
4
|
+
|
|
5
|
+
Anything visual or public-facing (viewer UI, docs theme, README, slides, release notes, social
|
|
6
|
+
images) follows [`brand/README.md`](brand/README.md): name always `freedyn2` in lower case, claim
|
|
7
|
+
"ai-first multibody dynamics.", colors and fonts from [`brand/tokens.json`](brand/tokens.json)
|
|
8
|
+
(CSS: [`brand/tokens.css`](brand/tokens.css)), logos from [`brand/logo/`](brand/logo/). Do not
|
|
9
|
+
invent new colors or logo variants; extend the tokens instead.
|