morphopt 4.0.0__tar.gz → 4.0.2__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.
- {morphopt-4.0.0 → morphopt-4.0.2}/PKG-INFO +22 -13
- {morphopt-4.0.0 → morphopt-4.0.2}/README.md +21 -12
- {morphopt-4.0.0 → morphopt-4.0.2}/pyproject.toml +9 -2
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/__init__.py +55 -7
- morphopt-4.0.2/src/morphopt/codesign/__init__.py +16 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/codesign/constraints.py +48 -30
- morphopt-4.0.0/src/morphopt/codesign/geometry.py → morphopt-4.0.2/src/morphopt/codesign/offset_boundary_part.py +32 -34
- morphopt-4.0.2/src/morphopt/codesign/update_offset_boundary_part.py +29 -0
- morphopt-4.0.2/src/morphopt/constants.py +1188 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/__init__.py +5 -5
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/controller.py +15 -9
- morphopt-4.0.2/src/morphopt/optcore/modelparams/__init__.py +27 -0
- morphopt-4.0.2/src/morphopt/optcore/modelparams/base_model_component.py +16 -0
- morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/__init__.py +10 -0
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/basefeainterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/base_component.py +7 -15
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/bodyforceinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/body_force.py +6 -6
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/boundaryconditioninterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/boundary_condition.py +24 -7
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/contactinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/contact.py +30 -26
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/coupleinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/couple.py +8 -4
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/pointinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/point_load.py +3 -3
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/pressureinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/pressure.py +10 -6
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/referencepointinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/reference_point.py +4 -4
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/springinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/fea/spring.py +4 -4
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/modelparams/feaparams.py +18 -15
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/modelparams/geometry.py +7 -6
- morphopt-4.0.2/src/morphopt/optcore/modelparams/materials/__init__.py +11 -0
- morphopt-4.0.0/src/morphopt/optcore/modelparams/materialinterface/basematerialinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/materials/base_material.py +13 -12
- morphopt-4.0.0/src/morphopt/optcore/modelparams/materialinterface/homogeneousmaterial.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/materials/homogeneous_material.py +3 -3
- morphopt-4.0.0/src/morphopt/optcore/modelparams/materials.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/materialsparams.py +2 -2
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/modelparams/params.py +9 -4
- morphopt-4.0.2/src/morphopt/optcore/modelparams/parts/__init__.py +13 -0
- morphopt-4.0.0/src/morphopt/optcore/modelparams/partinterface/basepartinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/parts/base_part.py +13 -6
- morphopt-4.0.2/src/morphopt/optcore/modelparams/parts/box_part.py +146 -0
- morphopt-4.0.2/src/morphopt/optcore/modelparams/parts/cad_part.py +128 -0
- morphopt-4.0.0/src/morphopt/optcore/modelparams/partinterface/inppartinterface.py → morphopt-4.0.2/src/morphopt/optcore/modelparams/parts/inp_part.py +3 -3
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/objfunc.py +15 -9
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/protocal.py +9 -1
- morphopt-4.0.2/src/morphopt/optcore/quadrature.py +78 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/solver.py +45 -45
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/updaters.py +12 -10
- morphopt-4.0.2/src/morphopt/postprocess/__init__.py +9 -0
- morphopt-4.0.2/src/morphopt/postprocess/exporters.py +117 -0
- morphopt-4.0.2/src/morphopt/postprocess/fields.py +329 -0
- morphopt-4.0.2/src/morphopt/postprocess/native.py +81 -0
- morphopt-4.0.2/src/morphopt/shapeopt/__init__.py +25 -0
- morphopt-4.0.0/src/morphopt/shapeopt/boundarypartinterface.py → morphopt-4.0.2/src/morphopt/shapeopt/boundary_part.py +69 -39
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/meshgenerator.py +7 -4
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/boundarys.py +17 -9
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/distancesurface.py +27 -10
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/shapederivative.py +3 -3
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/surfacefairness.py +4 -4
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/volumemaximization.py +10 -7
- morphopt-4.0.2/src/morphopt/shapeopt/surfaces/__init__.py +28 -0
- morphopt-4.0.2/src/morphopt/shapeopt/surfaces/base_constraints.py +116 -0
- morphopt-4.0.0/src/morphopt/shapeopt/surfaceinterfaces/basesurfaceinterface.py → morphopt-4.0.2/src/morphopt/shapeopt/surfaces/base_surface.py +69 -32
- morphopt-4.0.2/src/morphopt/shapeopt/surfaces/bsp_constraints.py +91 -0
- morphopt-4.0.0/src/morphopt/shapeopt/surfaceinterfaces/bspsurfaceinterface.py → morphopt-4.0.2/src/morphopt/shapeopt/surfaces/bsp_surface.py +116 -46
- morphopt-4.0.2/src/morphopt/shapeopt/surfaces/cpgeo_constraints.py +211 -0
- morphopt-4.0.0/src/morphopt/shapeopt/surfaceinterfaces/cpgeosurfaceinterface.py → morphopt-4.0.2/src/morphopt/shapeopt/surfaces/cpgeo_surface.py +74 -42
- morphopt-4.0.0/src/morphopt/shapeopt/update_boundarypart.py → morphopt-4.0.2/src/morphopt/shapeopt/update_boundary_part.py +25 -17
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/boundarys.py +17 -12
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/densityfield.py +5 -1
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/simpmaterial.py +29 -14
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/update_simpmaterial.py +18 -11
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/__init__.py +10 -6
- morphopt-4.0.2/src/morphopt/ui/app.py +59 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/application/__init__.py +12 -2
- morphopt-4.0.2/src/morphopt/ui/application/cad.py +96 -0
- morphopt-4.0.0/src/morphopt/ui/widgets/code_completion.py → morphopt-4.0.2/src/morphopt/ui/application/completion.py +12 -18
- morphopt-4.0.2/src/morphopt/ui/application/definitions.py +215 -0
- morphopt-4.0.2/src/morphopt/ui/application/devices.py +14 -0
- morphopt-4.0.2/src/morphopt/ui/application/edit_history.py +202 -0
- morphopt-4.0.2/src/morphopt/ui/application/editing.py +404 -0
- morphopt-4.0.2/src/morphopt/ui/application/editor_routing.py +116 -0
- morphopt-4.0.2/src/morphopt/ui/application/expressions.py +43 -0
- morphopt-4.0.2/src/morphopt/ui/application/fields.py +113 -0
- morphopt-4.0.2/src/morphopt/ui/application/finite_element.py +216 -0
- morphopt-4.0.2/src/morphopt/ui/application/part_sets.py +101 -0
- morphopt-4.0.2/src/morphopt/ui/application/quickstart.py +741 -0
- morphopt-4.0.2/src/morphopt/ui/application/result_fields.py +94 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/application/results.py +44 -2
- morphopt-4.0.2/src/morphopt/ui/application/runs.py +289 -0
- morphopt-4.0.2/src/morphopt/ui/application/updaters.py +187 -0
- {morphopt-4.0.0/src/morphopt/ui/widgets → morphopt-4.0.2/src/morphopt/ui/application}/values.py +35 -38
- morphopt-4.0.2/src/morphopt/ui/application_icon.py +49 -0
- morphopt-4.0.2/src/morphopt/ui/assets/morphopt.svg +48 -0
- morphopt-4.0.2/src/morphopt/ui/codegen/assets.py +88 -0
- morphopt-4.0.2/src/morphopt/ui/codegen/custom_classes.py +450 -0
- morphopt-4.0.2/src/morphopt/ui/codegen/generator.py +1317 -0
- morphopt-4.0.2/src/morphopt/ui/fea_worker.py +67 -0
- morphopt-4.0.2/src/morphopt/ui/i18n.py +134 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/launcher.py +28 -43
- morphopt-4.0.2/src/morphopt/ui/locales/en-US.json +1181 -0
- morphopt-4.0.2/src/morphopt/ui/locales/zh-CN.json +1181 -0
- morphopt-4.0.2/src/morphopt/ui/mainwindow.py +681 -0
- morphopt-4.0.2/src/morphopt/ui/model/__init__.py +38 -0
- morphopt-4.0.2/src/morphopt/ui/model/base_nodes.py +691 -0
- morphopt-4.0.2/src/morphopt/ui/model/chamberlayout.py +164 -0
- morphopt-4.0.2/src/morphopt/ui/model/configuration.py +101 -0
- morphopt-4.0.2/src/morphopt/ui/model/fields.py +38 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/model/loaders.py +3 -4
- morphopt-4.0.2/src/morphopt/ui/model/material_models.py +15 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/__init__.py +168 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/cad.py +665 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/custom_code.py +116 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/loads.py +426 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/materials.py +347 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/objectives.py +68 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/parts.py +351 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/penalties.py +321 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/structural.py +616 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/surfaces.py +267 -0
- morphopt-4.0.2/src/morphopt/ui/model/node_types/symmetry.py +172 -0
- morphopt-4.0.2/src/morphopt/ui/model/problem.py +1521 -0
- morphopt-4.0.2/src/morphopt/ui/model/registry.py +280 -0
- morphopt-4.0.2/src/morphopt/ui/observe_panel.py +611 -0
- morphopt-4.0.2/src/morphopt/ui/presentation/__init__.py +1 -0
- morphopt-4.0.2/src/morphopt/ui/presentation/edit_history.py +12 -0
- morphopt-4.0.2/src/morphopt/ui/presentation/history.py +83 -0
- morphopt-4.0.2/src/morphopt/ui/presentation/labels.py +329 -0
- morphopt-4.0.2/src/morphopt/ui/presentation/navigation.py +337 -0
- morphopt-4.0.2/src/morphopt/ui/refresh.py +116 -0
- morphopt-4.0.2/src/morphopt/ui/schemes/__init__.py +26 -0
- morphopt-4.0.2/src/morphopt/ui/schemes/base.py +391 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/schemes/snippets.py +24 -39
- morphopt-4.0.2/src/morphopt/ui/theme/__init__.py +56 -0
- morphopt-4.0.2/src/morphopt/ui/theme/manager.py +135 -0
- morphopt-4.0.2/src/morphopt/ui/theme/palette.py +389 -0
- morphopt-4.0.2/src/morphopt/ui/theme/styles/__init__.py +9 -0
- morphopt-4.0.2/src/morphopt/ui/theme/styles/base.qss +26 -0
- morphopt-4.0.2/src/morphopt/ui/theme/styles/controls.qss +119 -0
- morphopt-4.0.2/src/morphopt/ui/theme/styles/inputs.qss +23 -0
- morphopt-4.0.2/src/morphopt/ui/theme/stylesheet.py +34 -0
- morphopt-4.0.2/src/morphopt/ui/theme/themes/__init__.py +11 -0
- morphopt-4.0.2/src/morphopt/ui/theme/themes/dark.py +86 -0
- morphopt-4.0.2/src/morphopt/ui/theme/themes/light.py +114 -0
- morphopt-4.0.2/src/morphopt/ui/visualization/__init__.py +42 -0
- morphopt-4.0.2/src/morphopt/ui/visualization/assets.py +50 -0
- morphopt-4.0.2/src/morphopt/ui/visualization/geometry.py +1059 -0
- morphopt-4.0.2/src/morphopt/ui/visualization/loads.py +554 -0
- morphopt-4.0.2/src/morphopt/ui/visualization/scene.py +165 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/asset_browser.py +240 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/widgets/codeeditor.py +119 -65
- morphopt-4.0.2/src/morphopt/ui/widgets/collection_controls.py +147 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/controller_editor.py +138 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/custom_classes.py +585 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/definition_actions.py +669 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/definition_manager.py +648 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/edit_history.py +364 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/editor.py +305 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/editor_pages.py +64 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/elided_label.py +47 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/file_dialogs.py +216 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/finite_element.py +768 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/helper_editor.py +223 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/language_selector.py +43 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/model_tree.py +627 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/objective_editor.py +905 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/observation_pages.py +375 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/param_form.py +282 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/plot_style.py +44 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/preview_renderer.py +840 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/quickstart.py +1179 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/result_path.py +73 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/run_dialogs.py +69 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/widgets/solver_editor.py +89 -70
- morphopt-4.0.2/src/morphopt/ui/widgets/source_view.py +23 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/stepmatrix.py +207 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/template_insert_dialog.py +153 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/theme_selector.py +48 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/updater_editor.py +929 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/values.py +31 -0
- morphopt-4.0.2/src/morphopt/ui/widgets/viewer.py +441 -0
- morphopt-4.0.2/src/morphopt/ui/workbench.py +890 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/utils/__init__.py +1 -1
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/utils/gradient_check.py +57 -33
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/utils/history_read.py +5 -3
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt.egg-info/PKG-INFO +22 -13
- morphopt-4.0.2/src/morphopt.egg-info/SOURCES.txt +197 -0
- morphopt-4.0.0/src/morphopt/codesign/__init__.py +0 -23
- morphopt-4.0.0/src/morphopt/codesign/feaparams.py +0 -66
- morphopt-4.0.0/src/morphopt/codesign/geometryparams.py +0 -47
- morphopt-4.0.0/src/morphopt/codesign/params.py +0 -4
- morphopt-4.0.0/src/morphopt/optcore/modelparams/__init__.py +0 -14
- morphopt-4.0.0/src/morphopt/optcore/modelparams/feainterface/__init__.py +0 -10
- morphopt-4.0.0/src/morphopt/optcore/modelparams/materialinterface/__init__.py +0 -11
- morphopt-4.0.0/src/morphopt/optcore/modelparams/partinterface/__init__.py +0 -17
- morphopt-4.0.0/src/morphopt/optcore/modelparams/partinterface/torchfeapartinterface.py +0 -177
- morphopt-4.0.0/src/morphopt/shapeopt/__init__.py +0 -12
- morphopt-4.0.0/src/morphopt/shapeopt/surfaceinterfaces/__init__.py +0 -21
- morphopt-4.0.0/src/morphopt/ui/app.py +0 -64
- morphopt-4.0.0/src/morphopt/ui/application/definitions.py +0 -171
- morphopt-4.0.0/src/morphopt/ui/application/editor_routing.py +0 -52
- morphopt-4.0.0/src/morphopt/ui/application/runs.py +0 -138
- morphopt-4.0.0/src/morphopt/ui/codegen/generator.py +0 -816
- morphopt-4.0.0/src/morphopt/ui/i18n.py +0 -74
- morphopt-4.0.0/src/morphopt/ui/mainwindow.py +0 -205
- morphopt-4.0.0/src/morphopt/ui/model/__init__.py +0 -20
- morphopt-4.0.0/src/morphopt/ui/model/modelinfo.py +0 -118
- morphopt-4.0.0/src/morphopt/ui/model/problem.py +0 -2487
- morphopt-4.0.0/src/morphopt/ui/model/schemas.py +0 -1343
- morphopt-4.0.0/src/morphopt/ui/observe_panel.py +0 -788
- morphopt-4.0.0/src/morphopt/ui/schemes/__init__.py +0 -16
- morphopt-4.0.0/src/morphopt/ui/schemes/base.py +0 -353
- morphopt-4.0.0/src/morphopt/ui/templates/cantilever_beam.npz +0 -0
- morphopt-4.0.0/src/morphopt/ui/templates/multidesign.morph +0 -443
- morphopt-4.0.0/src/morphopt/ui/templates/shapeopt.morph +0 -202
- morphopt-4.0.0/src/morphopt/ui/templates/simp.morph +0 -262
- morphopt-4.0.0/src/morphopt/ui/widgets/editor.py +0 -565
- morphopt-4.0.0/src/morphopt/ui/widgets/model_tree.py +0 -868
- morphopt-4.0.0/src/morphopt/ui/widgets/objective_editor.py +0 -236
- morphopt-4.0.0/src/morphopt/ui/widgets/observation_pages.py +0 -380
- morphopt-4.0.0/src/morphopt/ui/widgets/param_form.py +0 -159
- morphopt-4.0.0/src/morphopt/ui/widgets/run_dialogs.py +0 -149
- morphopt-4.0.0/src/morphopt/ui/widgets/stepmatrix.py +0 -225
- morphopt-4.0.0/src/morphopt/ui/widgets/template_insert_dialog.py +0 -204
- morphopt-4.0.0/src/morphopt/ui/widgets/torchfea_model_editor.py +0 -508
- morphopt-4.0.0/src/morphopt/ui/widgets/updater_editor.py +0 -826
- morphopt-4.0.0/src/morphopt/ui/widgets/viewer.py +0 -505
- morphopt-4.0.0/src/morphopt/ui/workbench.py +0 -639
- morphopt-4.0.0/src/morphopt.egg-info/SOURCES.txt +0 -118
- {morphopt-4.0.0 → morphopt-4.0.2}/setup.cfg +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/opt_runner.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/history.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/optcore/modelparams/baseparam.py +0 -0
- /morphopt-4.0.0/src/morphopt/optcore/modelparams/materialinterface/materialmodels.py → /morphopt-4.0.2/src/morphopt/optcore/modelparams/materials/models.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/__init__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/shapeopt/objectivefuncs/basefuncs.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/__init__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/__init__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/basefuncs.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/sensitivity.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/simp/objectivefuncs/volfrac.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/taskoptmization.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/__main__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/codegen/__init__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt/ui/widgets/__init__.py +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt.egg-info/dependency_links.txt +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt.egg-info/entry_points.txt +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt.egg-info/requires.txt +0 -0
- {morphopt-4.0.0 → morphopt-4.0.2}/src/morphopt.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morphopt
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.2
|
|
4
4
|
Summary: A morphing optimization framework using PyTorch and torchfea.
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -28,14 +28,14 @@ Requires-Dist: pytest>=8.0; extra == "test"
|
|
|
28
28
|
|
|
29
29
|
**Developed by Zenan Song**
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
MorphOpt is a differentiable structural optimization framework that combines the adjoint method with automatic differentiation (AD). The sensitivity corresponds to the virtual work of residual force derivatives on the adjoint displacement field, computed via a single backpropagation through the residual graph. MorphOpt provides a unified interface for geometry, load, and material definition, calls torchfea for GPU-accelerated differentiable nonlinear FEA and adjoint-AD sensitivity, and employs a trust-region optimizer with L-BFGS for design updates. Validated on SIMP topology optimization with B-spline density fields and pneumatic soft robot shape optimization with deformation-dependent follower loads.
|
|
32
32
|
|
|
33
33
|
## Features
|
|
34
34
|
|
|
35
35
|
- Custom model definition covering geometry, material, and load parameters
|
|
36
36
|
- Differentiable FEA via torchfea with automatic solving and sensitivity propagation
|
|
37
37
|
- L-BFGS and trust-region methods for parameter updates within a subproblem framework
|
|
38
|
-
-
|
|
38
|
+
- Component customization through framework class inheritance
|
|
39
39
|
|
|
40
40
|
## Quick Start
|
|
41
41
|
|
|
@@ -47,7 +47,7 @@ pip install morphopt
|
|
|
47
47
|
|
|
48
48
|
Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
49
49
|
|
|
50
|
-
> **Optimizations are run as scripts.** Each job is an ordinary Python file that calls `morphopt.start_optimization(...)`. It runs headlessly in a terminal (local or remote), and
|
|
50
|
+
> **Optimizations are run as scripts.** Each job is an ordinary Python file that calls `morphopt.start_optimization(...)`. It runs headlessly in a terminal (local or remote), and optimization runs can be stopped and resumed from their result folders. Script execution is the recommended way to run jobs.
|
|
51
51
|
|
|
52
52
|
1. **Run a minimal example** — execute it directly in a terminal:
|
|
53
53
|
|
|
@@ -59,7 +59,7 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
59
59
|
python examples/gripper.py
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
2. **Run
|
|
62
|
+
2. **Run a custom job** — copy an example as a starting point, configure the geometry, material, loads, updater, and objective, and launch it as a script:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
python my_task.py
|
|
@@ -67,20 +67,29 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
67
67
|
|
|
68
68
|
Each run writes its results (logs, FEA files, restart script) into a timestamped result folder under the run root.
|
|
69
69
|
|
|
70
|
-
3. **
|
|
70
|
+
3. **Graphical interface.** The GUI supports problem definition, optimization monitoring, and result inspection in one window. It also exports runnable Python scripts (`.py`) for execution in the UI or a terminal.
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
73
|
morphopt-ui # console command, available after `pip install morphopt`
|
|
74
|
-
# python -m morphopt.ui
|
|
74
|
+
# Alternative entry point: python -m morphopt.ui
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
The
|
|
77
|
+
The GUI opens directly into the full definition workbench with its standard sections present and no problem setup prefilled. Definitions can be created directly in the workbench or generated through **Quickstart**. Quickstart provides shape and topology optimization settings, geometry definitions, and weighted objective terms with associated load conditions. Workspace terms select their driving pressure channels and use boundary integration. Generated problems stay editable and can be saved or exported as runnable scripts.
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
The [UI quick start](docs/UIguide.md) covers the complete example from model definition to optimization and result inspection. The [script quick start](docs/scriptguide.md) provides the equivalent runnable Python task.
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
### Numeric configuration
|
|
82
|
+
|
|
83
|
+
Shared UI defaults and tunable kernel parameters live in [`src/morphopt/constants.py`](src/morphopt/constants.py), grouped under `CONSTANT.UI` and `CONSTANT.KERNEL`. Code accesses them directly, for example `CONSTANT.UI.VIEWER.RENDER.LABEL_FONT_SIZE` or `CONSTANT.KERNEL.SOLVER.NUM_PROCESS`. Edit a value there to change its default; restart MorphOpt for the change to take effect. Coordinate indices, tensor dimensions, and coefficients that define mathematical formulas remain in code. UI translations remain in JSON files under `src/morphopt/ui/locales/`.
|
|
84
|
+
|
|
85
|
+
### Documentation
|
|
86
|
+
|
|
87
|
+
| Workflow | Quick start | Module and interface reference |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| Python script | [Start an optimization](docs/scriptguide.md) | [Define and extend each module](docs/scriptreference.md) |
|
|
90
|
+
| Graphical UI | [Create and run the example](docs/UIguide.md) | [Modules, parameters and interface definitions](docs/UIreference.md) |
|
|
91
|
+
|
|
92
|
+
The [documentation index](docs/README.md) includes the reading order and automatic section numbering commands. Theory and code architecture are documented separately under `docs/theory/` and `docs/codestructure/`.
|
|
84
93
|
|
|
85
94
|
## Directory Overview
|
|
86
95
|
|
|
@@ -101,7 +110,7 @@ Research use preferred. For production or commercial use, please evaluate and en
|
|
|
101
110
|
|
|
102
111
|
## Citation
|
|
103
112
|
|
|
104
|
-
|
|
113
|
+
Research using MorphOpt can cite the following publications:
|
|
105
114
|
|
|
106
115
|
- TRO 2023
|
|
107
116
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
**Developed by Zenan Song**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
MorphOpt is a differentiable structural optimization framework that combines the adjoint method with automatic differentiation (AD). The sensitivity corresponds to the virtual work of residual force derivatives on the adjoint displacement field, computed via a single backpropagation through the residual graph. MorphOpt provides a unified interface for geometry, load, and material definition, calls torchfea for GPU-accelerated differentiable nonlinear FEA and adjoint-AD sensitivity, and employs a trust-region optimizer with L-BFGS for design updates. Validated on SIMP topology optimization with B-spline density fields and pneumatic soft robot shape optimization with deformation-dependent follower loads.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- Custom model definition covering geometry, material, and load parameters
|
|
10
10
|
- Differentiable FEA via torchfea with automatic solving and sensitivity propagation
|
|
11
11
|
- L-BFGS and trust-region methods for parameter updates within a subproblem framework
|
|
12
|
-
-
|
|
12
|
+
- Component customization through framework class inheritance
|
|
13
13
|
|
|
14
14
|
## Quick Start
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@ pip install morphopt
|
|
|
21
21
|
|
|
22
22
|
Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
23
23
|
|
|
24
|
-
> **Optimizations are run as scripts.** Each job is an ordinary Python file that calls `morphopt.start_optimization(...)`. It runs headlessly in a terminal (local or remote), and
|
|
24
|
+
> **Optimizations are run as scripts.** Each job is an ordinary Python file that calls `morphopt.start_optimization(...)`. It runs headlessly in a terminal (local or remote), and optimization runs can be stopped and resumed from their result folders. Script execution is the recommended way to run jobs.
|
|
25
25
|
|
|
26
26
|
1. **Run a minimal example** — execute it directly in a terminal:
|
|
27
27
|
|
|
@@ -33,7 +33,7 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
33
33
|
python examples/gripper.py
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
2. **Run
|
|
36
|
+
2. **Run a custom job** — copy an example as a starting point, configure the geometry, material, loads, updater, and objective, and launch it as a script:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
python my_task.py
|
|
@@ -41,20 +41,29 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
41
41
|
|
|
42
42
|
Each run writes its results (logs, FEA files, restart script) into a timestamped result folder under the run root.
|
|
43
43
|
|
|
44
|
-
3. **
|
|
44
|
+
3. **Graphical interface.** The GUI supports problem definition, optimization monitoring, and result inspection in one window. It also exports runnable Python scripts (`.py`) for execution in the UI or a terminal.
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
morphopt-ui # console command, available after `pip install morphopt`
|
|
48
|
-
# python -m morphopt.ui
|
|
48
|
+
# Alternative entry point: python -m morphopt.ui
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
The
|
|
51
|
+
The GUI opens directly into the full definition workbench with its standard sections present and no problem setup prefilled. Definitions can be created directly in the workbench or generated through **Quickstart**. Quickstart provides shape and topology optimization settings, geometry definitions, and weighted objective terms with associated load conditions. Workspace terms select their driving pressure channels and use boundary integration. Generated problems stay editable and can be saved or exported as runnable scripts.
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
The [UI quick start](docs/UIguide.md) covers the complete example from model definition to optimization and result inspection. The [script quick start](docs/scriptguide.md) provides the equivalent runnable Python task.
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
### Numeric configuration
|
|
56
|
+
|
|
57
|
+
Shared UI defaults and tunable kernel parameters live in [`src/morphopt/constants.py`](src/morphopt/constants.py), grouped under `CONSTANT.UI` and `CONSTANT.KERNEL`. Code accesses them directly, for example `CONSTANT.UI.VIEWER.RENDER.LABEL_FONT_SIZE` or `CONSTANT.KERNEL.SOLVER.NUM_PROCESS`. Edit a value there to change its default; restart MorphOpt for the change to take effect. Coordinate indices, tensor dimensions, and coefficients that define mathematical formulas remain in code. UI translations remain in JSON files under `src/morphopt/ui/locales/`.
|
|
58
|
+
|
|
59
|
+
### Documentation
|
|
60
|
+
|
|
61
|
+
| Workflow | Quick start | Module and interface reference |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| Python script | [Start an optimization](docs/scriptguide.md) | [Define and extend each module](docs/scriptreference.md) |
|
|
64
|
+
| Graphical UI | [Create and run the example](docs/UIguide.md) | [Modules, parameters and interface definitions](docs/UIreference.md) |
|
|
65
|
+
|
|
66
|
+
The [documentation index](docs/README.md) includes the reading order and automatic section numbering commands. Theory and code architecture are documented separately under `docs/theory/` and `docs/codestructure/`.
|
|
58
67
|
|
|
59
68
|
## Directory Overview
|
|
60
69
|
|
|
@@ -75,7 +84,7 @@ Research use preferred. For production or commercial use, please evaluate and en
|
|
|
75
84
|
|
|
76
85
|
## Citation
|
|
77
86
|
|
|
78
|
-
|
|
87
|
+
Research using MorphOpt can cite the following publications:
|
|
79
88
|
|
|
80
89
|
- TRO 2023
|
|
81
90
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "morphopt"
|
|
3
|
-
version = "4.0.
|
|
3
|
+
version = "4.0.2"
|
|
4
4
|
description = "A morphing optimization framework using PyTorch and torchfea."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -39,5 +39,12 @@ testpaths = ["tests"]
|
|
|
39
39
|
pythonpath = ["src"]
|
|
40
40
|
addopts = "-ra"
|
|
41
41
|
|
|
42
|
+
[tool.ruff.lint]
|
|
43
|
+
extend-select = ["RUF022"]
|
|
44
|
+
|
|
42
45
|
[tool.setuptools.package-data]
|
|
43
|
-
"morphopt.ui" = [
|
|
46
|
+
"morphopt.ui" = [
|
|
47
|
+
"locales/*.json",
|
|
48
|
+
"theme/styles/*.qss",
|
|
49
|
+
"assets/*.svg",
|
|
50
|
+
]
|
|
@@ -67,21 +67,22 @@ def enable_logging(level=__logging.INFO, log_file=None, file_log_level=__logging
|
|
|
67
67
|
|
|
68
68
|
# region modules (loaded after the core classes they subclass)
|
|
69
69
|
from . import codesign, shapeopt, simp
|
|
70
|
+
from .codesign import OffsetBoundaryPart, UpdaterOffsetBoundaryPart
|
|
70
71
|
from .opt_runner import debug_optimization, start_optimization
|
|
71
72
|
from .optcore.controller import Controller
|
|
72
73
|
from .optcore.history import History
|
|
73
74
|
from .optcore.modelparams import (
|
|
74
|
-
|
|
75
|
+
BaseModelComponent,
|
|
76
|
+
BasePart,
|
|
77
|
+
BoxPart,
|
|
78
|
+
CADPart,
|
|
75
79
|
FEAParams,
|
|
76
80
|
GeometryParams,
|
|
77
|
-
|
|
81
|
+
INPPart,
|
|
78
82
|
MaterialsParams,
|
|
79
83
|
Params,
|
|
80
|
-
TorchFEAPartInterface,
|
|
81
|
-
load_model_assembly,
|
|
82
|
-
resolve_model_path,
|
|
83
84
|
)
|
|
84
|
-
from .optcore.modelparams.
|
|
85
|
+
from .optcore.modelparams.materials import HomogeneousMaterial
|
|
85
86
|
from .optcore.objfunc import ObjectiveFunction
|
|
86
87
|
from .optcore.protocal import (
|
|
87
88
|
ProtocalInitializable,
|
|
@@ -91,7 +92,14 @@ from .optcore.protocal import (
|
|
|
91
92
|
)
|
|
92
93
|
from .optcore.solver import Solver
|
|
93
94
|
from .optcore.updaters import Updaters
|
|
94
|
-
from .shapeopt import
|
|
95
|
+
from .shapeopt import (
|
|
96
|
+
BaseSurfaceConstraints,
|
|
97
|
+
BoundaryPart,
|
|
98
|
+
BspSurfaceRelationConstraint,
|
|
99
|
+
CPGEOSurfaceRelationConstraint,
|
|
100
|
+
SurfaceRelationConstraint,
|
|
101
|
+
UpdaterBoundaryPart,
|
|
102
|
+
)
|
|
95
103
|
from .simp import SIMP_BSPFieldMaterials, UpdaterSIMPMaterial
|
|
96
104
|
|
|
97
105
|
# endregion
|
|
@@ -101,3 +109,43 @@ from .utils import check_gradients, get_controller
|
|
|
101
109
|
# endregion
|
|
102
110
|
|
|
103
111
|
controller: Controller = None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
__all__ = [
|
|
115
|
+
"BaseModelComponent",
|
|
116
|
+
"BasePart",
|
|
117
|
+
"BaseSurfaceConstraints",
|
|
118
|
+
"BoundaryPart",
|
|
119
|
+
"BoxPart",
|
|
120
|
+
"BspSurfaceRelationConstraint",
|
|
121
|
+
"CADPart",
|
|
122
|
+
"CPGEOSurfaceRelationConstraint",
|
|
123
|
+
"Controller",
|
|
124
|
+
"FEAParams",
|
|
125
|
+
"GeometryParams",
|
|
126
|
+
"History",
|
|
127
|
+
"HomogeneousMaterial",
|
|
128
|
+
"INPPart",
|
|
129
|
+
"MaterialsParams",
|
|
130
|
+
"ObjectiveFunction",
|
|
131
|
+
"OffsetBoundaryPart",
|
|
132
|
+
"Params",
|
|
133
|
+
"ProtocalInitializable",
|
|
134
|
+
"ProtocalSavable",
|
|
135
|
+
"ProtocalUpdatable",
|
|
136
|
+
"ProtocalVisualizable",
|
|
137
|
+
"SIMP_BSPFieldMaterials",
|
|
138
|
+
"Solver",
|
|
139
|
+
"SurfaceRelationConstraint",
|
|
140
|
+
"UpdaterBoundaryPart",
|
|
141
|
+
"UpdaterOffsetBoundaryPart",
|
|
142
|
+
"UpdaterSIMPMaterial",
|
|
143
|
+
"Updaters",
|
|
144
|
+
"check_gradients",
|
|
145
|
+
"codesign",
|
|
146
|
+
"debug_optimization",
|
|
147
|
+
"get_controller",
|
|
148
|
+
"shapeopt",
|
|
149
|
+
"simp",
|
|
150
|
+
"start_optimization",
|
|
151
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Cavity offset Parts and their geometry updater.
|
|
2
|
+
|
|
3
|
+
Compose parameters, objectives, solvers and updater collections using the
|
|
4
|
+
common morphopt interfaces. SIMP materials use the simp interfaces.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .offset_boundary_part import OffsetBoundaryPart
|
|
8
|
+
from .update_offset_boundary_part import UpdaterOffsetBoundaryPart
|
|
9
|
+
from .constraints import InwardCurvatureRadius, OffsetSurfaceMinThickness
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"OffsetBoundaryPart",
|
|
13
|
+
"UpdaterOffsetBoundaryPart",
|
|
14
|
+
"InwardCurvatureRadius",
|
|
15
|
+
"OffsetSurfaceMinThickness",
|
|
16
|
+
]
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import torch
|
|
2
2
|
|
|
3
|
+
from ..constants import CONSTANT
|
|
3
4
|
from ..shapeopt.objectivefuncs.basefuncs import BaseConstraints
|
|
4
|
-
from .
|
|
5
|
+
from .offset_boundary_part import OffsetBoundaryPart
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class InwardCurvatureRadius(BaseConstraints):
|
|
@@ -17,13 +18,13 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
17
18
|
self,
|
|
18
19
|
surface_start: int = 1,
|
|
19
20
|
surface_ids: list[int] | None = None,
|
|
20
|
-
margin: float =
|
|
21
|
-
margin_ratio: float =
|
|
22
|
-
barrier_thre_ratio: float =
|
|
23
|
-
barrier_ratio: float =
|
|
24
|
-
p: int =
|
|
25
|
-
penalty_scale: float =
|
|
26
|
-
hard_violation_beta: float =
|
|
21
|
+
margin: float = CONSTANT.KERNEL.CODESIGN.CURVATURE_MARGIN,
|
|
22
|
+
margin_ratio: float = CONSTANT.KERNEL.CODESIGN.CURVATURE_MARGIN_RATIO,
|
|
23
|
+
barrier_thre_ratio: float = CONSTANT.KERNEL.CODESIGN.CURVATURE_BARRIER_THRESHOLD_RATIO,
|
|
24
|
+
barrier_ratio: float = CONSTANT.KERNEL.CODESIGN.BARRIER_PENALTY_RATIO,
|
|
25
|
+
p: int = CONSTANT.KERNEL.CODESIGN.BARRIER_EXPONENT,
|
|
26
|
+
penalty_scale: float = CONSTANT.KERNEL.CODESIGN.PENALTY_SCALE,
|
|
27
|
+
hard_violation_beta: float = CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_BETA,
|
|
27
28
|
normal_sign: float = 1.0,
|
|
28
29
|
) -> None:
|
|
29
30
|
"""
|
|
@@ -71,7 +72,9 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
71
72
|
|
|
72
73
|
@staticmethod
|
|
73
74
|
def _principal_curvatures(
|
|
74
|
-
rdu: torch.Tensor,
|
|
75
|
+
rdu: torch.Tensor,
|
|
76
|
+
rdu2: torch.Tensor,
|
|
77
|
+
eps: float = CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
75
78
|
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
76
79
|
normal0 = torch.cross(rdu[:, :, 1], rdu[:, :, 0], dim=1)
|
|
77
80
|
normal = normal0 / (normal0.norm(dim=1, keepdim=True) + eps)
|
|
@@ -96,11 +99,11 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
96
99
|
"""Take the Part this constraint is evaluated for.
|
|
97
100
|
|
|
98
101
|
The geometry updater hands over the Part it evaluates; only a
|
|
99
|
-
:class:`~morphopt.codesign.
|
|
102
|
+
:class:`~morphopt.codesign.OffsetBoundaryPart` carries a
|
|
100
103
|
shell, so anything else is rejected here.
|
|
101
104
|
"""
|
|
102
105
|
super().initialize(r0=r0, rdu0=rdu0, *args, **kwargs)
|
|
103
|
-
if not isinstance(part_interface,
|
|
106
|
+
if not isinstance(part_interface, OffsetBoundaryPart):
|
|
104
107
|
raise TypeError(
|
|
105
108
|
f"{type(self).__name__} is evaluated for one co-design Part "
|
|
106
109
|
f"(got {type(part_interface).__name__})."
|
|
@@ -127,9 +130,15 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
127
130
|
if t <= 0:
|
|
128
131
|
continue
|
|
129
132
|
|
|
130
|
-
margin_abs = max(
|
|
133
|
+
margin_abs = max(
|
|
134
|
+
float((self.margin_ratio * t) + self.margin),
|
|
135
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
136
|
+
)
|
|
131
137
|
k_limit = 1.0 / (t + margin_abs)
|
|
132
|
-
barrier_thre = max(
|
|
138
|
+
barrier_thre = max(
|
|
139
|
+
k_limit * self.barrier_thre_ratio,
|
|
140
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
141
|
+
)
|
|
133
142
|
|
|
134
143
|
k1, k2 = self._principal_curvatures(rdu[i], rdu2[i])
|
|
135
144
|
|
|
@@ -146,7 +155,8 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
146
155
|
rel_violation = (violation[index] / barrier_thre).clamp(min=0.0)
|
|
147
156
|
hard_boost = torch.exp(
|
|
148
157
|
(self.hard_violation_beta * (rel_violation - 1.0)).clamp(
|
|
149
|
-
min=0.0,
|
|
158
|
+
min=0.0,
|
|
159
|
+
max=CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_EXPONENT_MAX,
|
|
150
160
|
)
|
|
151
161
|
)
|
|
152
162
|
penalty_strong = self.penalty_scale * penalty * hard_boost
|
|
@@ -168,16 +178,16 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
168
178
|
surface_start: int = 1,
|
|
169
179
|
surface_ids: list[int] | None = None,
|
|
170
180
|
min_distance: float | None = None,
|
|
171
|
-
search_ratio: float =
|
|
172
|
-
barrier_thre_ratio: float =
|
|
173
|
-
barrier_ratio: float =
|
|
174
|
-
p: int =
|
|
175
|
-
penalty_scale: float =
|
|
176
|
-
hard_violation_beta: float =
|
|
181
|
+
search_ratio: float = CONSTANT.KERNEL.CODESIGN.THICKNESS_SEARCH_RATIO,
|
|
182
|
+
barrier_thre_ratio: float = CONSTANT.KERNEL.CODESIGN.THICKNESS_BARRIER_THRESHOLD_RATIO,
|
|
183
|
+
barrier_ratio: float = CONSTANT.KERNEL.CODESIGN.BARRIER_PENALTY_RATIO,
|
|
184
|
+
p: int = CONSTANT.KERNEL.CODESIGN.BARRIER_EXPONENT,
|
|
185
|
+
penalty_scale: float = CONSTANT.KERNEL.CODESIGN.PENALTY_SCALE,
|
|
186
|
+
hard_violation_beta: float = CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_BETA,
|
|
177
187
|
normal_sign: float = 1.0,
|
|
178
|
-
normal_opposition_thre: float =
|
|
179
|
-
normal_min: float =
|
|
180
|
-
normal_max: float =
|
|
188
|
+
normal_opposition_thre: float = CONSTANT.KERNEL.CODESIGN.NORMAL_OPPOSITION_THRESHOLD,
|
|
189
|
+
normal_min: float = CONSTANT.KERNEL.CODESIGN.NORMAL_TRANSITION_MIN,
|
|
190
|
+
normal_max: float = CONSTANT.KERNEL.CODESIGN.NORMAL_TRANSITION_MAX,
|
|
181
191
|
) -> None:
|
|
182
192
|
"""
|
|
183
193
|
Initialize the minimum thickness constraint for the offset surface.
|
|
@@ -233,7 +243,10 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
233
243
|
@staticmethod
|
|
234
244
|
def _surface_normals(rdu_sf: torch.Tensor) -> torch.Tensor:
|
|
235
245
|
normal0 = torch.cross(rdu_sf[:, :, 1], rdu_sf[:, :, 0], dim=1)
|
|
236
|
-
normals = normal0 / (
|
|
246
|
+
normals = normal0 / (
|
|
247
|
+
normal0.norm(dim=1, keepdim=True)
|
|
248
|
+
+ CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE
|
|
249
|
+
)
|
|
237
250
|
return normals
|
|
238
251
|
|
|
239
252
|
def _offset_points(
|
|
@@ -249,17 +262,17 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
249
262
|
if self.min_distance is not None
|
|
250
263
|
else (2.0 * thickness)
|
|
251
264
|
)
|
|
252
|
-
return max(dmin,
|
|
265
|
+
return max(dmin, CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE)
|
|
253
266
|
|
|
254
267
|
def initialize(self, r0, rdu0, *args, part_interface=None, **kwargs) -> None:
|
|
255
268
|
"""Take the Part this constraint is evaluated for and pair its points.
|
|
256
269
|
|
|
257
270
|
The geometry updater hands over the Part it evaluates; only a
|
|
258
|
-
:class:`~morphopt.codesign.
|
|
271
|
+
:class:`~morphopt.codesign.OffsetBoundaryPart` carries a
|
|
259
272
|
shell, so anything else is rejected here.
|
|
260
273
|
"""
|
|
261
274
|
super().initialize(r0=r0, rdu0=rdu0, *args, **kwargs)
|
|
262
|
-
if not isinstance(part_interface,
|
|
275
|
+
if not isinstance(part_interface, OffsetBoundaryPart):
|
|
263
276
|
raise TypeError(
|
|
264
277
|
f"{type(self).__name__} is evaluated for one co-design Part "
|
|
265
278
|
f"(got {type(part_interface).__name__})."
|
|
@@ -318,7 +331,8 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
318
331
|
if thickness <= 0:
|
|
319
332
|
continue
|
|
320
333
|
barrier_thre = max(
|
|
321
|
-
self._min_distance(thickness) * self.barrier_thre_ratio,
|
|
334
|
+
self._min_distance(thickness) * self.barrier_thre_ratio,
|
|
335
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
322
336
|
)
|
|
323
337
|
|
|
324
338
|
# Base surface normals (offset surface shares same normal direction)
|
|
@@ -343,7 +357,10 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
343
357
|
r_sf=r[sf_idx], rdu_sf=rdu[sf_idx], thickness=thickness
|
|
344
358
|
)
|
|
345
359
|
delta = roff[pairs_n[0]] - roff[pairs_n[1]]
|
|
346
|
-
dist = torch.sqrt(
|
|
360
|
+
dist = torch.sqrt(
|
|
361
|
+
(delta * delta).sum(dim=1)
|
|
362
|
+
+ CONSTANT.KERNEL.CODESIGN.DISTANCE_SQUARED_TOLERANCE
|
|
363
|
+
)
|
|
347
364
|
|
|
348
365
|
violation = mindist_n - dist + barrier_thre
|
|
349
366
|
indexl, l = self.barrier_function(
|
|
@@ -361,7 +378,8 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
361
378
|
rel_violation = (violation[indexl] / barrier_thre).clamp(min=0.0)
|
|
362
379
|
hard_boost = torch.exp(
|
|
363
380
|
(self.hard_violation_beta * (rel_violation - 1.0)).clamp(
|
|
364
|
-
min=0.0,
|
|
381
|
+
min=0.0,
|
|
382
|
+
max=CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_EXPONENT_MAX,
|
|
365
383
|
)
|
|
366
384
|
)
|
|
367
385
|
penalty_strong = self.penalty_scale * l * hard_boost * np_smooth
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Co-design boundary part
|
|
1
|
+
"""Co-design boundary part: cavity surfaces with an offset shell.
|
|
2
2
|
|
|
3
3
|
The co-design (``codesign``) scheme extends the shape-optimization boundary
|
|
4
4
|
description with a solid shell: every cavity surface (index ``1..n``) is offset
|
|
@@ -13,12 +13,13 @@ import numpy as np
|
|
|
13
13
|
import torch
|
|
14
14
|
import torchfea
|
|
15
15
|
|
|
16
|
-
from ..
|
|
16
|
+
from ..constants import CONSTANT
|
|
17
|
+
from ..shapeopt.boundary_part import BoundaryPart
|
|
17
18
|
|
|
18
|
-
__all__ = ["
|
|
19
|
+
__all__ = ["OffsetBoundaryPart"]
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
class
|
|
22
|
+
class OffsetBoundaryPart(BoundaryPart):
|
|
22
23
|
"""Boundary-surface geometry whose cavity surfaces carry a solid shell.
|
|
23
24
|
|
|
24
25
|
Parameters
|
|
@@ -31,7 +32,7 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
31
32
|
|
|
32
33
|
def __init__(
|
|
33
34
|
self,
|
|
34
|
-
shell_thickness: float =
|
|
35
|
+
shell_thickness: float = CONSTANT.KERNEL.CODESIGN_GEOMETRY.DEFAULT_SHELL_THICKNESS,
|
|
35
36
|
num_layers: int = 1,
|
|
36
37
|
**kwargs: object,
|
|
37
38
|
) -> None:
|
|
@@ -40,17 +41,16 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
40
41
|
self.shell_thickness: float = float(shell_thickness)
|
|
41
42
|
"""Total thickness of the offset shell on the cavity surfaces."""
|
|
42
43
|
|
|
43
|
-
self.num_layers: int =
|
|
44
|
+
self.num_layers: int = int(num_layers)
|
|
44
45
|
"""Number of wedge layers through the shell thickness."""
|
|
45
46
|
|
|
46
47
|
self._node_idx: list[np.ndarray] = []
|
|
47
48
|
"""Node indices of each offset layer (0 = base surface mesh)."""
|
|
48
49
|
|
|
49
|
-
self.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"""Element-id offset of the shell block (0-based)."""
|
|
50
|
+
if self.shell_thickness <= 0:
|
|
51
|
+
raise ValueError("shell_thickness must be positive.")
|
|
52
|
+
if self.num_layers < 1:
|
|
53
|
+
raise ValueError("num_layers must be at least one.")
|
|
54
54
|
|
|
55
55
|
# ------------------------------------------------------------- shell mesh
|
|
56
56
|
def _compute_normals(self, base_nodes: torch.Tensor) -> torch.Tensor:
|
|
@@ -60,8 +60,9 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
60
60
|
surface = self.surfaceinterfaces[index]
|
|
61
61
|
normals.append(
|
|
62
62
|
surface.get_normals(
|
|
63
|
-
torch.
|
|
64
|
-
|
|
63
|
+
torch.as_tensor(
|
|
64
|
+
surface.surf_node_uv, device=base_nodes.device,
|
|
65
|
+
dtype=base_nodes.dtype,
|
|
65
66
|
)
|
|
66
67
|
)
|
|
67
68
|
)
|
|
@@ -76,16 +77,19 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
76
77
|
"""Add the offset shell wedge elements to the meshed Part."""
|
|
77
78
|
return self._build_shell_c3d6(part)
|
|
78
79
|
|
|
79
|
-
def
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
def build_part(self, path_result=None, pools=None) -> torchfea.Part:
|
|
81
|
+
"""Build and validate the offset wedges, including quadratic conversion."""
|
|
82
|
+
part = super().build_part(path_result=path_result, pools=pools)
|
|
83
|
+
shell = part.elems["C3D6"]
|
|
84
|
+
shell.initialize(nodes=part.nodes)
|
|
85
|
+
weights = shell.gaussian_weight
|
|
86
|
+
if not torch.isfinite(weights).all() or (weights <= 0).any():
|
|
87
|
+
raise ValueError(f"Invalid offset shell mesh on Part {self.part_name!r}.")
|
|
88
|
+
return part
|
|
83
89
|
|
|
90
|
+
def _build_shell_c3d6(self, part: torchfea.Part) -> torchfea.Part:
|
|
84
91
|
# Ensure surface elements exist so we can query triangle meshes.
|
|
85
|
-
|
|
86
|
-
part.surfaces.initialize(part)
|
|
87
|
-
except Exception:
|
|
88
|
-
pass
|
|
92
|
+
part.surfaces.initialize(part)
|
|
89
93
|
|
|
90
94
|
tri_by_surface: dict[int, np.ndarray] = {}
|
|
91
95
|
tri_local_by_surface: dict[int, np.ndarray] = {}
|
|
@@ -100,7 +104,7 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
100
104
|
cavity_order.append(sidx)
|
|
101
105
|
tri_by_surface[sidx] = tri
|
|
102
106
|
base_ids_blocks.append(
|
|
103
|
-
np.
|
|
107
|
+
np.asarray(self.surfaceinterfaces[sidx].surf_node_idx, dtype=int)
|
|
104
108
|
)
|
|
105
109
|
|
|
106
110
|
if len(tri_by_surface) == 0:
|
|
@@ -115,7 +119,6 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
115
119
|
local_map = -np.ones((int(part.nodes.shape[0]),), dtype=int)
|
|
116
120
|
local_map[base_ids] = np.arange(base_ids.shape[0], dtype=int)
|
|
117
121
|
|
|
118
|
-
tri_local_all = []
|
|
119
122
|
for sidx in cavity_order:
|
|
120
123
|
tri_global = tri_by_surface[sidx]
|
|
121
124
|
tri_local = local_map[tri_global]
|
|
@@ -125,8 +128,6 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
125
128
|
)
|
|
126
129
|
tri_local = tri_local.astype(int)
|
|
127
130
|
tri_local_by_surface[sidx] = tri_local
|
|
128
|
-
tri_local_all.append(tri_local)
|
|
129
|
-
self._tri_local = np.concatenate(tri_local_all, axis=0).astype(int)
|
|
130
131
|
|
|
131
132
|
device = part.nodes.device
|
|
132
133
|
base_ids_t = torch.as_tensor(base_ids, dtype=torch.long, device=device)
|
|
@@ -155,7 +156,6 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
155
156
|
continue
|
|
156
157
|
existing_max = max(existing_max, int(element._elems_index.max().item()))
|
|
157
158
|
elem_offset = int(existing_max + 1)
|
|
158
|
-
self._shell_elem_offset = elem_offset
|
|
159
159
|
|
|
160
160
|
# Build linear wedge connectivity (C3D6) for all layers.
|
|
161
161
|
wedge6_blocks = []
|
|
@@ -217,10 +217,7 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
217
217
|
)
|
|
218
218
|
|
|
219
219
|
# Refresh the surfaces cache to include the newly added offset surfaces.
|
|
220
|
-
|
|
221
|
-
part.surfaces.initialize(part)
|
|
222
|
-
except Exception:
|
|
223
|
-
pass
|
|
220
|
+
part.surfaces.initialize(part)
|
|
224
221
|
|
|
225
222
|
return part
|
|
226
223
|
|
|
@@ -231,9 +228,6 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
231
228
|
"""Update the Part nodes and keep the offset layers consistent."""
|
|
232
229
|
super().modify_assembly(design_sensitivity_vars, assembly)
|
|
233
230
|
|
|
234
|
-
if len(self._node_idx) == 0 or self._tri_local is None:
|
|
235
|
-
return
|
|
236
|
-
|
|
237
231
|
part = assembly.get_part(self.part_name)
|
|
238
232
|
nodes = part.nodes.clone()
|
|
239
233
|
|
|
@@ -262,4 +256,8 @@ class CodesignBoundaryPartInterface(BoundaryPartInterface):
|
|
|
262
256
|
@staticmethod
|
|
263
257
|
def _default_opacity(index: int) -> float:
|
|
264
258
|
"""The solid volume is hidden so the shell stays visible."""
|
|
265
|
-
return
|
|
259
|
+
return (
|
|
260
|
+
0.0
|
|
261
|
+
if index == 0
|
|
262
|
+
else CONSTANT.KERNEL.VISUALIZATION.OFFSET_SHELL_SURFACE_OPACITY
|
|
263
|
+
)
|