morphopt 3.2.2__tar.gz → 4.0.1__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-3.2.2/src/morphopt.egg-info → morphopt-4.0.1}/PKG-INFO +12 -4
- morphopt-3.2.2/PKG-INFO → morphopt-4.0.1/README.md +7 -25
- {morphopt-3.2.2 → morphopt-4.0.1}/pyproject.toml +23 -3
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/__init__.py +52 -29
- morphopt-4.0.1/src/morphopt/codesign/__init__.py +16 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/codesign/constraints.py +169 -70
- morphopt-4.0.1/src/morphopt/codesign/offset_boundary_part.py +263 -0
- morphopt-4.0.1/src/morphopt/codesign/update_offset_boundary_part.py +29 -0
- morphopt-4.0.1/src/morphopt/constants.py +1275 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/opt_runner.py +36 -19
- morphopt-4.0.1/src/morphopt/optcore/__init__.py +24 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/optcore/controller.py +183 -121
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/optcore/history.py +174 -141
- morphopt-4.0.1/src/morphopt/optcore/modelparams/__init__.py +33 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/base_model_component.py +16 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/baseparam.py +170 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/__init__.py +10 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/basefeainterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/base_component.py +19 -6
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/bodyforceinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/body_force.py +27 -17
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/boundaryconditioninterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/boundary_condition.py +24 -7
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/contactinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/contact.py +18 -14
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/coupleinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/couple.py +8 -4
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/pointinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/point_load.py +3 -3
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/pressureinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/pressure.py +10 -6
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/referencepointinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/reference_point.py +4 -4
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/springinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/fea/spring.py +4 -4
- morphopt-4.0.1/src/morphopt/optcore/modelparams/feaparams.py +137 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/geometry.py +66 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/materials/__init__.py +11 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/basematerialinterface.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/materials/base_material.py +39 -16
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/homogeneousmaterial.py → morphopt-4.0.1/src/morphopt/optcore/modelparams/materials/homogeneous_material.py +3 -3
- morphopt-4.0.1/src/morphopt/optcore/modelparams/materialsparams.py +25 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/optcore/modelparams/params.py +69 -51
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/__init__.py +21 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/base_part.py +212 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/box_part.py +146 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/cad_part.py +128 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/inp_part.py +72 -0
- morphopt-4.0.1/src/morphopt/optcore/modelparams/parts/torch_fea_part.py +177 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/optcore/objfunc.py +29 -19
- morphopt-4.0.1/src/morphopt/optcore/protocal.py +130 -0
- morphopt-4.0.1/src/morphopt/optcore/quadrature.py +78 -0
- morphopt-4.0.1/src/morphopt/optcore/solver.py +239 -0
- morphopt-4.0.1/src/morphopt/optcore/updaters.py +781 -0
- morphopt-4.0.1/src/morphopt/postprocess/__init__.py +9 -0
- morphopt-4.0.1/src/morphopt/postprocess/exporters.py +117 -0
- morphopt-4.0.1/src/morphopt/postprocess/fields.py +321 -0
- morphopt-4.0.1/src/morphopt/shapeopt/__init__.py +25 -0
- morphopt-4.0.1/src/morphopt/shapeopt/boundary_part.py +532 -0
- morphopt-4.0.1/src/morphopt/shapeopt/meshgenerator.py +312 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/shapeopt/objectivefuncs/boundarys.py +17 -9
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/shapeopt/objectivefuncs/distancesurface.py +27 -10
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/shapeopt/objectivefuncs/shapederivative.py +88 -63
- morphopt-4.0.1/src/morphopt/shapeopt/objectivefuncs/surfacefairness.py +66 -0
- morphopt-4.0.1/src/morphopt/shapeopt/objectivefuncs/volumemaximization.py +61 -0
- morphopt-4.0.1/src/morphopt/shapeopt/surfaces/__init__.py +28 -0
- morphopt-4.0.1/src/morphopt/shapeopt/surfaces/base_constraints.py +116 -0
- morphopt-3.2.2/src/morphopt/shapeopt/geometryinterfaces/basesurfaceinterface.py → morphopt-4.0.1/src/morphopt/shapeopt/surfaces/base_surface.py +118 -77
- morphopt-4.0.1/src/morphopt/shapeopt/surfaces/bsp_constraints.py +91 -0
- morphopt-3.2.2/src/morphopt/shapeopt/geometryinterfaces/bspsurfaceinterface.py → morphopt-4.0.1/src/morphopt/shapeopt/surfaces/bsp_surface.py +126 -109
- morphopt-4.0.1/src/morphopt/shapeopt/surfaces/cpgeo_constraints.py +211 -0
- morphopt-3.2.2/src/morphopt/shapeopt/geometryinterfaces/cpgeosurfaceinterface.py → morphopt-4.0.1/src/morphopt/shapeopt/surfaces/cpgeo_surface.py +79 -70
- morphopt-4.0.1/src/morphopt/shapeopt/update_boundary_part.py +460 -0
- morphopt-4.0.1/src/morphopt/simp/__init__.py +10 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/boundarys.py +17 -12
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/densityfield.py +5 -1
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/volfrac.py +13 -17
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/simpmaterial.py +492 -263
- morphopt-4.0.1/src/morphopt/simp/update_simpmaterial.py +410 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/taskoptmization.py +44 -17
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/__init__.py +10 -5
- morphopt-4.0.1/src/morphopt/ui/app.py +51 -0
- morphopt-4.0.1/src/morphopt/ui/application/__init__.py +42 -0
- morphopt-4.0.1/src/morphopt/ui/application/cad.py +85 -0
- morphopt-3.2.2/src/morphopt/ui/widgets/code_completion.py → morphopt-4.0.1/src/morphopt/ui/application/completion.py +22 -34
- morphopt-4.0.1/src/morphopt/ui/application/definitions.py +212 -0
- morphopt-4.0.1/src/morphopt/ui/application/devices.py +14 -0
- morphopt-4.0.1/src/morphopt/ui/application/edit_history.py +202 -0
- morphopt-4.0.1/src/morphopt/ui/application/editing.py +401 -0
- morphopt-4.0.1/src/morphopt/ui/application/editor_routing.py +116 -0
- morphopt-4.0.1/src/morphopt/ui/application/expressions.py +43 -0
- morphopt-4.0.1/src/morphopt/ui/application/fields.py +116 -0
- morphopt-4.0.1/src/morphopt/ui/application/finite_element.py +193 -0
- morphopt-4.0.1/src/morphopt/ui/application/imported_models.py +79 -0
- morphopt-4.0.1/src/morphopt/ui/application/part_sets.py +117 -0
- morphopt-4.0.1/src/morphopt/ui/application/quickstart.py +741 -0
- morphopt-4.0.1/src/morphopt/ui/application/results.py +161 -0
- morphopt-4.0.1/src/morphopt/ui/application/runs.py +283 -0
- morphopt-4.0.1/src/morphopt/ui/application/updaters.py +187 -0
- {morphopt-3.2.2/src/morphopt/ui/widgets → morphopt-4.0.1/src/morphopt/ui/application}/values.py +35 -38
- morphopt-4.0.1/src/morphopt/ui/codegen/custom_classes.py +433 -0
- morphopt-4.0.1/src/morphopt/ui/codegen/generator.py +1203 -0
- morphopt-4.0.1/src/morphopt/ui/fea_worker.py +53 -0
- morphopt-4.0.1/src/morphopt/ui/i18n.py +136 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/launcher.py +6 -4
- morphopt-4.0.1/src/morphopt/ui/locales/en-US.json +1207 -0
- morphopt-4.0.1/src/morphopt/ui/locales/zh-CN.json +1207 -0
- morphopt-4.0.1/src/morphopt/ui/mainwindow.py +444 -0
- morphopt-4.0.1/src/morphopt/ui/model/__init__.py +38 -0
- morphopt-4.0.1/src/morphopt/ui/model/base_nodes.py +690 -0
- morphopt-4.0.1/src/morphopt/ui/model/chamberlayout.py +164 -0
- morphopt-4.0.1/src/morphopt/ui/model/configuration.py +101 -0
- morphopt-4.0.1/src/morphopt/ui/model/fields.py +38 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/model/loaders.py +3 -4
- morphopt-4.0.1/src/morphopt/ui/model/material_models.py +15 -0
- morphopt-4.0.1/src/morphopt/ui/model/modelinfo.py +119 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/__init__.py +170 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/cad.py +665 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/custom_code.py +116 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/loads.py +426 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/materials.py +347 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/objectives.py +68 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/parts.py +445 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/penalties.py +321 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/structural.py +612 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/surfaces.py +267 -0
- morphopt-4.0.1/src/morphopt/ui/model/node_types/symmetry.py +172 -0
- morphopt-4.0.1/src/morphopt/ui/model/problem.py +1759 -0
- morphopt-4.0.1/src/morphopt/ui/model/registry.py +282 -0
- morphopt-4.0.1/src/morphopt/ui/observe_panel.py +558 -0
- morphopt-4.0.1/src/morphopt/ui/presentation/__init__.py +1 -0
- morphopt-4.0.1/src/morphopt/ui/presentation/edit_history.py +12 -0
- morphopt-4.0.1/src/morphopt/ui/presentation/history.py +83 -0
- morphopt-4.0.1/src/morphopt/ui/presentation/labels.py +327 -0
- morphopt-4.0.1/src/morphopt/ui/presentation/navigation.py +337 -0
- morphopt-4.0.1/src/morphopt/ui/refresh.py +109 -0
- morphopt-4.0.1/src/morphopt/ui/schemes/__init__.py +26 -0
- morphopt-4.0.1/src/morphopt/ui/schemes/base.py +391 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/schemes/snippets.py +27 -42
- morphopt-4.0.1/src/morphopt/ui/theme/__init__.py +56 -0
- morphopt-4.0.1/src/morphopt/ui/theme/manager.py +135 -0
- morphopt-4.0.1/src/morphopt/ui/theme/palette.py +385 -0
- morphopt-4.0.1/src/morphopt/ui/theme/styles/__init__.py +9 -0
- morphopt-4.0.1/src/morphopt/ui/theme/styles/base.qss +26 -0
- morphopt-4.0.1/src/morphopt/ui/theme/styles/controls.qss +88 -0
- morphopt-4.0.1/src/morphopt/ui/theme/styles/inputs.qss +23 -0
- morphopt-4.0.1/src/morphopt/ui/theme/stylesheet.py +34 -0
- morphopt-4.0.1/src/morphopt/ui/theme/themes/__init__.py +11 -0
- morphopt-4.0.1/src/morphopt/ui/theme/themes/dark.py +86 -0
- morphopt-4.0.1/src/morphopt/ui/theme/themes/light.py +114 -0
- morphopt-4.0.1/src/morphopt/ui/visualization/__init__.py +42 -0
- morphopt-4.0.1/src/morphopt/ui/visualization/geometry.py +1057 -0
- morphopt-4.0.1/src/morphopt/ui/visualization/loads.py +554 -0
- morphopt-4.0.1/src/morphopt/ui/visualization/scene.py +145 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/widgets/codeeditor.py +58 -35
- morphopt-4.0.1/src/morphopt/ui/widgets/collection_controls.py +102 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/controller_editor.py +137 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/custom_classes.py +469 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/definition_actions.py +569 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/definition_manager.py +569 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/edit_history.py +359 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/editor.py +252 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/editor_pages.py +57 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/file_dialogs.py +158 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/finite_element.py +493 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/helper_editor.py +140 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/language_selector.py +43 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/model_tree.py +550 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/objective_editor.py +879 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/observation_pages.py +359 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/param_form.py +228 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/plot_style.py +28 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/preview_renderer.py +628 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/quickstart.py +971 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/run_dialogs.py +125 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/widgets/solver_editor.py +51 -66
- morphopt-4.0.1/src/morphopt/ui/widgets/source_view.py +23 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/stepmatrix.py +191 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/template_insert_dialog.py +122 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/theme_selector.py +46 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/torchfea_model_editor.py +406 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/updater_editor.py +786 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/values.py +33 -0
- morphopt-4.0.1/src/morphopt/ui/widgets/viewer.py +283 -0
- morphopt-4.0.1/src/morphopt/ui/workbench.py +909 -0
- morphopt-3.2.2/README.md → morphopt-4.0.1/src/morphopt.egg-info/PKG-INFO +33 -1
- morphopt-4.0.1/src/morphopt.egg-info/SOURCES.txt +192 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt.egg-info/requires.txt +4 -1
- morphopt-3.2.2/src/morphopt/codesign/__init__.py +0 -20
- morphopt-3.2.2/src/morphopt/codesign/feaparams.py +0 -80
- morphopt-3.2.2/src/morphopt/codesign/geometry.py +0 -362
- morphopt-3.2.2/src/morphopt/codesign/params.py +0 -4
- morphopt-3.2.2/src/morphopt/optcore/__init__.py +0 -8
- morphopt-3.2.2/src/morphopt/optcore/baseobject.py +0 -48
- morphopt-3.2.2/src/morphopt/optcore/modelparams/__init__.py +0 -5
- morphopt-3.2.2/src/morphopt/optcore/modelparams/baseparam.py +0 -133
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feainterface/__init__.py +0 -10
- morphopt-3.2.2/src/morphopt/optcore/modelparams/feaparams.py +0 -239
- morphopt-3.2.2/src/morphopt/optcore/modelparams/geometry.py +0 -251
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/__init__.py +0 -11
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materials.py +0 -175
- morphopt-3.2.2/src/morphopt/optcore/solver.py +0 -179
- morphopt-3.2.2/src/morphopt/optcore/updaters.py +0 -384
- morphopt-3.2.2/src/morphopt/shapeopt/__init__.py +0 -10
- morphopt-3.2.2/src/morphopt/shapeopt/geometryinterfaces/__init__.py +0 -3
- morphopt-3.2.2/src/morphopt/shapeopt/geometryparams.py +0 -794
- morphopt-3.2.2/src/morphopt/shapeopt/objectivefuncs/surfacefairness.py +0 -38
- morphopt-3.2.2/src/morphopt/shapeopt/objectivefuncs/volumemaximization.py +0 -25
- morphopt-3.2.2/src/morphopt/shapeopt/objfunc.py +0 -13
- morphopt-3.2.2/src/morphopt/shapeopt/update_geometry.py +0 -335
- morphopt-3.2.2/src/morphopt/simp/__init__.py +0 -12
- morphopt-3.2.2/src/morphopt/simp/solver.py +0 -41
- morphopt-3.2.2/src/morphopt/simp/update_material.py +0 -324
- morphopt-3.2.2/src/morphopt/ui/app.py +0 -64
- morphopt-3.2.2/src/morphopt/ui/codegen/generator.py +0 -586
- morphopt-3.2.2/src/morphopt/ui/i18n.py +0 -74
- morphopt-3.2.2/src/morphopt/ui/mainwindow.py +0 -209
- morphopt-3.2.2/src/morphopt/ui/model/__init__.py +0 -20
- morphopt-3.2.2/src/morphopt/ui/model/problem.py +0 -1220
- morphopt-3.2.2/src/morphopt/ui/model/schemas.py +0 -847
- morphopt-3.2.2/src/morphopt/ui/observe_panel.py +0 -968
- morphopt-3.2.2/src/morphopt/ui/schemes/__init__.py +0 -18
- morphopt-3.2.2/src/morphopt/ui/schemes/base.py +0 -206
- morphopt-3.2.2/src/morphopt/ui/schemes/codesign.py +0 -155
- morphopt-3.2.2/src/morphopt/ui/schemes/shapeopt.py +0 -104
- morphopt-3.2.2/src/morphopt/ui/schemes/simp.py +0 -112
- morphopt-3.2.2/src/morphopt/ui/widgets/editor.py +0 -370
- morphopt-3.2.2/src/morphopt/ui/widgets/model_tree.py +0 -565
- morphopt-3.2.2/src/morphopt/ui/widgets/objective_editor.py +0 -233
- morphopt-3.2.2/src/morphopt/ui/widgets/observation_pages.py +0 -246
- morphopt-3.2.2/src/morphopt/ui/widgets/param_form.py +0 -159
- morphopt-3.2.2/src/morphopt/ui/widgets/stepmatrix.py +0 -226
- morphopt-3.2.2/src/morphopt/ui/widgets/template_insert_dialog.py +0 -198
- morphopt-3.2.2/src/morphopt/ui/widgets/torchfea_model_editor.py +0 -428
- morphopt-3.2.2/src/morphopt/ui/widgets/updater_editor.py +0 -699
- morphopt-3.2.2/src/morphopt/ui/widgets/viewer.py +0 -352
- morphopt-3.2.2/src/morphopt/ui/workbench.py +0 -553
- morphopt-3.2.2/src/morphopt.egg-info/SOURCES.txt +0 -109
- morphopt-3.2.2/tests/test_fixedGeometry.py +0 -24
- morphopt-3.2.2/tests/test_path.py +0 -12
- morphopt-3.2.2/tests/test_ui.py +0 -62
- {morphopt-3.2.2 → morphopt-4.0.1}/setup.cfg +0 -0
- /morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/materialmodels.py → /morphopt-4.0.1/src/morphopt/optcore/modelparams/materials/models.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/shapeopt/objectivefuncs/__init__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/shapeopt/objectivefuncs/basefuncs.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/__init__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/basefuncs.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/simp/objectivefuncs/sensitivity.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/__main__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/codegen/__init__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/ui/widgets/__init__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/utils/__init__.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/utils/gradient_check.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt/utils/history_read.py +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt.egg-info/dependency_links.txt +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt.egg-info/entry_points.txt +0 -0
- {morphopt-3.2.2 → morphopt-4.0.1}/src/morphopt.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morphopt
|
|
3
|
-
Version:
|
|
4
|
-
Summary: A morphing optimization framework using PyTorch and
|
|
3
|
+
Version: 4.0.1
|
|
4
|
+
Summary: A morphing optimization framework using PyTorch and torchfea.
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
Requires-Dist: torch>=2.9.1
|
|
@@ -16,11 +16,13 @@ Requires-Dist: gmsh>=4.15.0
|
|
|
16
16
|
Requires-Dist: tabulate>=0.9.0
|
|
17
17
|
Requires-Dist: imageio>=2.37.3
|
|
18
18
|
Requires-Dist: bspmap>=1.0.3
|
|
19
|
-
Requires-Dist: torchfea>=1.1.
|
|
19
|
+
Requires-Dist: torchfea>=1.1.2
|
|
20
20
|
Requires-Dist: trimesh>=4.11.5
|
|
21
21
|
Requires-Dist: networkx>=3.6.1
|
|
22
22
|
Requires-Dist: scipy>=1.17.1
|
|
23
23
|
Requires-Dist: cpgeo>=1.0.12
|
|
24
|
+
Provides-Extra: test
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
24
26
|
|
|
25
27
|
# MorphOpt — A Differentiable Optimization Framework for Soft Structure & Morphology Design
|
|
26
28
|
|
|
@@ -72,7 +74,13 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
72
74
|
# python -m morphopt.ui works too (handy when running from a source code directory)
|
|
73
75
|
```
|
|
74
76
|
|
|
75
|
-
The
|
|
77
|
+
The GUI opens directly into the full definition workbench with its standard sections present and no problem setup prefilled. Build a definition yourself or use **Quickstart** to choose shape or topology optimization, define geometry separately, and add weighted objective terms with their own 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
|
+
|
|
79
|
+
The complete UI workflow (definition part + observer part) is described in [`docs/UIguide.md`](docs/UIguide.md).
|
|
80
|
+
|
|
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/`.
|
|
76
84
|
|
|
77
85
|
Further references:
|
|
78
86
|
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: morphopt
|
|
3
|
-
Version: 3.2.2
|
|
4
|
-
Summary: A morphing optimization framework using PyTorch and Abaqus.
|
|
5
|
-
Requires-Python: >=3.12
|
|
6
|
-
Description-Content-Type: text/markdown
|
|
7
|
-
Requires-Dist: torch>=2.9.1
|
|
8
|
-
Requires-Dist: torchvision>=0.15.1
|
|
9
|
-
Requires-Dist: numpy>=2.0.0
|
|
10
|
-
Requires-Dist: pypardiso>=0.4.7
|
|
11
|
-
Requires-Dist: pyside6>=6.8.0
|
|
12
|
-
Requires-Dist: pyvista>=0.47.1
|
|
13
|
-
Requires-Dist: pyvistaqt>=0.11.3
|
|
14
|
-
Requires-Dist: vtk>=9.6.1
|
|
15
|
-
Requires-Dist: gmsh>=4.15.0
|
|
16
|
-
Requires-Dist: tabulate>=0.9.0
|
|
17
|
-
Requires-Dist: imageio>=2.37.3
|
|
18
|
-
Requires-Dist: bspmap>=1.0.3
|
|
19
|
-
Requires-Dist: torchfea>=1.1.1
|
|
20
|
-
Requires-Dist: trimesh>=4.11.5
|
|
21
|
-
Requires-Dist: networkx>=3.6.1
|
|
22
|
-
Requires-Dist: scipy>=1.17.1
|
|
23
|
-
Requires-Dist: cpgeo>=1.0.12
|
|
24
|
-
|
|
25
1
|
# MorphOpt — A Differentiable Optimization Framework for Soft Structure & Morphology Design
|
|
26
2
|
|
|
27
3
|
**Developed by Zenan Song**
|
|
@@ -72,7 +48,13 @@ Requirements: Python ≥ 3.12; a PyTorch **float64** build is recommended.
|
|
|
72
48
|
# python -m morphopt.ui works too (handy when running from a source code directory)
|
|
73
49
|
```
|
|
74
50
|
|
|
75
|
-
The
|
|
51
|
+
The GUI opens directly into the full definition workbench with its standard sections present and no problem setup prefilled. Build a definition yourself or use **Quickstart** to choose shape or topology optimization, define geometry separately, and add weighted objective terms with their own 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
|
+
|
|
53
|
+
The complete UI workflow (definition part + observer part) is described in [`docs/UIguide.md`](docs/UIguide.md).
|
|
54
|
+
|
|
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/`.
|
|
76
58
|
|
|
77
59
|
Further references:
|
|
78
60
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "morphopt"
|
|
3
|
-
version = "
|
|
4
|
-
description = "A morphing optimization framework using PyTorch and
|
|
3
|
+
version = "4.0.1"
|
|
4
|
+
description = "A morphing optimization framework using PyTorch and torchfea."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
dependencies = [
|
|
@@ -17,7 +17,7 @@ dependencies = [
|
|
|
17
17
|
"tabulate>=0.9.0",
|
|
18
18
|
"imageio>=2.37.3",
|
|
19
19
|
"bspmap>=1.0.3",
|
|
20
|
-
"torchfea>=1.1.
|
|
20
|
+
"torchfea>=1.1.2",
|
|
21
21
|
"trimesh>=4.11.5",
|
|
22
22
|
"networkx>=3.6.1",
|
|
23
23
|
"scipy>=1.17.1",
|
|
@@ -27,3 +27,23 @@ dependencies = [
|
|
|
27
27
|
[project.scripts]
|
|
28
28
|
# console entry for the graphical UI (after `pip install morphopt`)
|
|
29
29
|
morphopt-ui = "morphopt.ui:run_app"
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
# Install with: python -m pip install -e ".[test]"
|
|
33
|
+
test = [
|
|
34
|
+
"pytest>=8.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[tool.pytest.ini_options]
|
|
38
|
+
testpaths = ["tests"]
|
|
39
|
+
pythonpath = ["src"]
|
|
40
|
+
addopts = "-ra"
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint]
|
|
43
|
+
extend-select = ["RUF022"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
"morphopt.ui" = [
|
|
47
|
+
"locales/*.json",
|
|
48
|
+
"theme/styles/*.qss",
|
|
49
|
+
]
|
|
@@ -13,6 +13,7 @@ if __sys.platform.startswith("linux"):
|
|
|
13
13
|
# region: Logging Configuration
|
|
14
14
|
import logging as __logging
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
def enable_logging(level=__logging.INFO, log_file=None, file_log_level=__logging.DEBUG):
|
|
17
18
|
"""
|
|
18
19
|
Enable logging for the FEA package.
|
|
@@ -25,7 +26,7 @@ def enable_logging(level=__logging.INFO, log_file=None, file_log_level=__logging
|
|
|
25
26
|
the path to a log file where logs will be written. If None, logs will only be printed to the console.
|
|
26
27
|
file_log_level : int
|
|
27
28
|
the logging level for the log file. Default is logging.INFO.
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
Examples
|
|
30
31
|
--------
|
|
31
32
|
>>> import torchfea
|
|
@@ -33,59 +34,81 @@ def enable_logging(level=__logging.INFO, log_file=None, file_log_level=__logging
|
|
|
33
34
|
"""
|
|
34
35
|
logger = __logging.getLogger(__name__)
|
|
35
36
|
logger.setLevel(min(level, file_log_level))
|
|
36
|
-
|
|
37
|
+
|
|
37
38
|
# clear existing handlers to avoid duplicate logs
|
|
38
39
|
logger.handlers.clear()
|
|
39
|
-
|
|
40
|
+
|
|
40
41
|
# logging to console
|
|
41
42
|
console = __logging.StreamHandler()
|
|
42
43
|
console.setLevel(level)
|
|
43
|
-
console.setFormatter(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
console.setFormatter(
|
|
45
|
+
__logging.Formatter(
|
|
46
|
+
"%(asctime)s | %(levelname)-7s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S"
|
|
47
|
+
)
|
|
48
|
+
)
|
|
47
49
|
logger.addHandler(console)
|
|
48
|
-
|
|
50
|
+
|
|
49
51
|
# logging to file if log_file is provided
|
|
50
52
|
if log_file:
|
|
51
|
-
file_handler = __logging.FileHandler(log_file, encoding=
|
|
53
|
+
file_handler = __logging.FileHandler(log_file, encoding="utf-8")
|
|
52
54
|
file_handler.setLevel(file_log_level)
|
|
53
|
-
file_handler.setFormatter(
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
file_handler.setFormatter(
|
|
56
|
+
__logging.Formatter(
|
|
57
|
+
"%(asctime)s | %(levelname)-7s | %(name)s | %(message)s"
|
|
58
|
+
)
|
|
59
|
+
)
|
|
56
60
|
logger.addHandler(file_handler)
|
|
57
61
|
|
|
58
62
|
return logger
|
|
59
|
-
# endregion
|
|
60
|
-
|
|
61
63
|
|
|
62
64
|
|
|
65
|
+
# endregion
|
|
63
66
|
|
|
64
67
|
|
|
65
|
-
# region
|
|
68
|
+
# region modules (loaded after the core classes they subclass)
|
|
69
|
+
from . import codesign, shapeopt, simp
|
|
70
|
+
from .opt_runner import debug_optimization, start_optimization
|
|
66
71
|
from .optcore.controller import Controller
|
|
72
|
+
from .optcore.history import History
|
|
67
73
|
from .optcore.modelparams import (
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
BaseModelComponent,
|
|
75
|
+
BasePart,
|
|
76
|
+
CADPart,
|
|
77
|
+
BoxPart,
|
|
78
|
+
FEAParams,
|
|
79
|
+
GeometryParams,
|
|
80
|
+
INPPart,
|
|
81
|
+
MaterialsParams,
|
|
82
|
+
Params,
|
|
83
|
+
TorchFEAPart,
|
|
84
|
+
load_model_assembly,
|
|
85
|
+
resolve_model_path,
|
|
86
|
+
)
|
|
87
|
+
from .optcore.modelparams.materials import HomogeneousMaterial
|
|
88
|
+
from .optcore.objfunc import ObjectiveFunction
|
|
89
|
+
from .optcore.protocal import (
|
|
90
|
+
ProtocalInitializable,
|
|
91
|
+
ProtocalSavable,
|
|
92
|
+
ProtocalUpdatable,
|
|
93
|
+
ProtocalVisualizable,
|
|
70
94
|
)
|
|
71
95
|
from .optcore.solver import Solver
|
|
72
|
-
from .optcore.modelparams import Params
|
|
73
96
|
from .optcore.updaters import Updaters
|
|
74
|
-
from .
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
from .shapeopt import (
|
|
98
|
+
BoundaryPart,
|
|
99
|
+
UpdaterBoundaryPart,
|
|
100
|
+
BaseSurfaceConstraints,
|
|
101
|
+
SurfaceRelationConstraint,
|
|
102
|
+
BspSurfaceRelationConstraint,
|
|
103
|
+
CPGEOSurfaceRelationConstraint,
|
|
104
|
+
)
|
|
105
|
+
from .codesign import OffsetBoundaryPart, UpdaterOffsetBoundaryPart
|
|
106
|
+
from .simp import SIMP_BSPFieldMaterials, UpdaterSIMPMaterial
|
|
80
107
|
|
|
81
|
-
# region modules
|
|
82
|
-
from . import shapeopt
|
|
83
|
-
from . import codesign
|
|
84
|
-
from . import simp
|
|
85
108
|
# endregion
|
|
86
|
-
|
|
87
109
|
# region scripts
|
|
88
110
|
from .utils import check_gradients, get_controller
|
|
111
|
+
|
|
89
112
|
# endregion
|
|
90
113
|
|
|
91
114
|
controller: Controller = None
|
|
@@ -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):
|
|
@@ -15,23 +16,21 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
15
16
|
|
|
16
17
|
def __init__(
|
|
17
18
|
self,
|
|
18
|
-
geometry: CodesignGeometry,
|
|
19
19
|
surface_start: int = 1,
|
|
20
20
|
surface_ids: list[int] | None = None,
|
|
21
|
-
margin: float =
|
|
22
|
-
margin_ratio: float =
|
|
23
|
-
barrier_thre_ratio: float =
|
|
24
|
-
barrier_ratio: float =
|
|
25
|
-
p: int =
|
|
26
|
-
penalty_scale: float =
|
|
27
|
-
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,
|
|
28
28
|
normal_sign: float = 1.0,
|
|
29
29
|
) -> None:
|
|
30
30
|
"""
|
|
31
31
|
Initialize the inward curvature radius constraint.
|
|
32
32
|
|
|
33
33
|
Args:
|
|
34
|
-
geometry (CodesignGeometry): The geometry parameters containing the surfaces.
|
|
35
34
|
surface_start (int, optional): The starting index of surfaces to apply the constraint. Defaults to 1.
|
|
36
35
|
surface_ids (list[int] | None, optional): The specific surface indices to apply the constraint. If None, applies to all surfaces starting from surface_start. Defaults to None.
|
|
37
36
|
margin (float, optional): The absolute margin added to thickness for curvature limit. Defaults to 0.4.
|
|
@@ -42,17 +41,16 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
42
41
|
penalty_scale (float, optional): Global multiplier for this constraint penalty. Defaults to 1e3.
|
|
43
42
|
hard_violation_beta (float, optional): Exponential amplification factor for large violations. Defaults to 8.0.
|
|
44
43
|
normal_sign (float, optional): The sign to determine inward direction. Use 1.0 if normals point outward, -1.0 if normals point inward. Defaults to 1.0.
|
|
45
|
-
|
|
46
|
-
"""
|
|
47
44
|
|
|
45
|
+
"""
|
|
48
46
|
|
|
49
47
|
super().__init__()
|
|
50
48
|
|
|
51
|
-
self.geometry = geometry
|
|
52
|
-
"""Stores the geometry used by InwardCurvatureRadius."""
|
|
53
49
|
self.surface_start = int(surface_start)
|
|
54
50
|
"""Stores the surface start used by InwardCurvatureRadius."""
|
|
55
|
-
self.surface_ids =
|
|
51
|
+
self.surface_ids = (
|
|
52
|
+
None if surface_ids is None else [int(i) for i in surface_ids]
|
|
53
|
+
)
|
|
56
54
|
"""Stores the surface ids used by InwardCurvatureRadius."""
|
|
57
55
|
|
|
58
56
|
self.margin = margin
|
|
@@ -73,7 +71,11 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
73
71
|
"""Stores the normal sign used by InwardCurvatureRadius."""
|
|
74
72
|
|
|
75
73
|
@staticmethod
|
|
76
|
-
def _principal_curvatures(
|
|
74
|
+
def _principal_curvatures(
|
|
75
|
+
rdu: torch.Tensor,
|
|
76
|
+
rdu2: torch.Tensor,
|
|
77
|
+
eps: float = CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
78
|
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
77
79
|
normal0 = torch.cross(rdu[:, :, 1], rdu[:, :, 0], dim=1)
|
|
78
80
|
normal = normal0 / (normal0.norm(dim=1, keepdim=True) + eps)
|
|
79
81
|
|
|
@@ -93,26 +95,51 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
93
95
|
k2 = 0.5 * (tr - root)
|
|
94
96
|
return k1, k2
|
|
95
97
|
|
|
98
|
+
def initialize(self, r0, rdu0, *args, part_interface=None, **kwargs) -> None:
|
|
99
|
+
"""Take the Part this constraint is evaluated for.
|
|
100
|
+
|
|
101
|
+
The geometry updater hands over the Part it evaluates; only a
|
|
102
|
+
:class:`~morphopt.codesign.OffsetBoundaryPart` carries a
|
|
103
|
+
shell, so anything else is rejected here.
|
|
104
|
+
"""
|
|
105
|
+
super().initialize(r0=r0, rdu0=rdu0, *args, **kwargs)
|
|
106
|
+
if not isinstance(part_interface, OffsetBoundaryPart):
|
|
107
|
+
raise TypeError(
|
|
108
|
+
f"{type(self).__name__} is evaluated for one co-design Part "
|
|
109
|
+
f"(got {type(part_interface).__name__})."
|
|
110
|
+
)
|
|
111
|
+
self.shell_thickness = float(part_interface.shell_thickness)
|
|
112
|
+
|
|
96
113
|
def _selected_surface_ids(self, n_surface: int) -> list[int]:
|
|
97
114
|
if self.surface_ids is None:
|
|
98
115
|
return [i for i in range(max(self.surface_start, 0), n_surface)]
|
|
99
116
|
return [i for i in self.surface_ids if 0 <= i < n_surface]
|
|
100
117
|
|
|
101
|
-
def __call__(
|
|
118
|
+
def __call__(
|
|
119
|
+
self,
|
|
120
|
+
r: list[torch.Tensor],
|
|
121
|
+
rdu: list[torch.Tensor],
|
|
122
|
+
rdu2: list[torch.Tensor],
|
|
123
|
+
*args,
|
|
124
|
+
**kwargs,
|
|
125
|
+
) -> torch.Tensor:
|
|
102
126
|
loss = torch.zeros(1, device=r[0].device, dtype=r[0].dtype)
|
|
103
127
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
margin_abs = (self.margin_ratio * t) + self.margin
|
|
109
|
-
margin_abs = max(float(margin_abs), 1e-12)
|
|
110
|
-
t_eff = t + margin_abs
|
|
128
|
+
for i in self._selected_surface_ids(len(r)):
|
|
129
|
+
t = self.shell_thickness
|
|
130
|
+
if t <= 0:
|
|
131
|
+
continue
|
|
111
132
|
|
|
112
|
-
|
|
113
|
-
|
|
133
|
+
margin_abs = max(
|
|
134
|
+
float((self.margin_ratio * t) + self.margin),
|
|
135
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
136
|
+
)
|
|
137
|
+
k_limit = 1.0 / (t + margin_abs)
|
|
138
|
+
barrier_thre = max(
|
|
139
|
+
k_limit * self.barrier_thre_ratio,
|
|
140
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
141
|
+
)
|
|
114
142
|
|
|
115
|
-
for i in self._selected_surface_ids(len(r)):
|
|
116
143
|
k1, k2 = self._principal_curvatures(rdu[i], rdu2[i])
|
|
117
144
|
|
|
118
145
|
k1_in = torch.relu(self.normal_sign * k1)
|
|
@@ -120,16 +147,24 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
120
147
|
k_inward = torch.maximum(k1_in, k2_in)
|
|
121
148
|
|
|
122
149
|
violation = k_inward - k_limit
|
|
123
|
-
index, penalty = self.barrier_function(
|
|
150
|
+
index, penalty = self.barrier_function(
|
|
151
|
+
violation, barrier_thre, self.barrier_ratio, self.p
|
|
152
|
+
)
|
|
124
153
|
if index.numel() > 0:
|
|
125
154
|
# Strong amplification: base polynomial barrier + exponential hard-violation boost.
|
|
126
155
|
rel_violation = (violation[index] / barrier_thre).clamp(min=0.0)
|
|
127
|
-
hard_boost = torch.exp(
|
|
156
|
+
hard_boost = torch.exp(
|
|
157
|
+
(self.hard_violation_beta * (rel_violation - 1.0)).clamp(
|
|
158
|
+
min=0.0,
|
|
159
|
+
max=CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_EXPONENT_MAX,
|
|
160
|
+
)
|
|
161
|
+
)
|
|
128
162
|
penalty_strong = self.penalty_scale * penalty * hard_boost
|
|
129
163
|
loss = loss + (self.scaler[i][index] * penalty_strong).sum()
|
|
130
164
|
|
|
131
165
|
return loss
|
|
132
166
|
|
|
167
|
+
|
|
133
168
|
class OffsetSurfaceMinThickness(BaseConstraints):
|
|
134
169
|
"""
|
|
135
170
|
Enforce a minimum distance on the offset surface to reduce self-intersection risk.
|
|
@@ -140,28 +175,36 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
140
175
|
|
|
141
176
|
def __init__(
|
|
142
177
|
self,
|
|
143
|
-
geometry: CodesignGeometry,
|
|
144
178
|
surface_start: int = 1,
|
|
145
179
|
surface_ids: list[int] | None = None,
|
|
146
180
|
min_distance: float | None = None,
|
|
147
|
-
search_ratio: float =
|
|
148
|
-
barrier_thre_ratio: float =
|
|
149
|
-
barrier_ratio: float =
|
|
150
|
-
p: int =
|
|
151
|
-
penalty_scale: float =
|
|
152
|
-
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,
|
|
153
187
|
normal_sign: float = 1.0,
|
|
154
|
-
normal_opposition_thre: float =
|
|
155
|
-
normal_min: float =
|
|
156
|
-
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,
|
|
157
191
|
) -> None:
|
|
192
|
+
"""
|
|
193
|
+
Initialize the minimum thickness constraint for the offset surface.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
surface_start (int, optional): The starting index of surfaces to apply the constraint. Defaults to 1.
|
|
197
|
+
surface_ids (list[int] | None, optional): The specific surface indices to apply the constraint. If None, applies to all surfaces starting from surface_start. Defaults to None.
|
|
198
|
+
min_distance (float | None, optional): The required minimum distance.
|
|
199
|
+
Defaults to twice the shell thickness.
|
|
200
|
+
"""
|
|
158
201
|
super().__init__()
|
|
159
202
|
|
|
160
|
-
self.geometry = geometry
|
|
161
|
-
"""Stores the geometry used by OffsetSurfaceMinThickness."""
|
|
162
203
|
self.surface_start = int(surface_start)
|
|
163
204
|
"""Stores the surface start used by OffsetSurfaceMinThickness."""
|
|
164
|
-
self.surface_ids =
|
|
205
|
+
self.surface_ids = (
|
|
206
|
+
None if surface_ids is None else [int(i) for i in surface_ids]
|
|
207
|
+
)
|
|
165
208
|
"""Stores the surface ids used by OffsetSurfaceMinThickness."""
|
|
166
209
|
|
|
167
210
|
self.min_distance = min_distance
|
|
@@ -200,36 +243,66 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
200
243
|
@staticmethod
|
|
201
244
|
def _surface_normals(rdu_sf: torch.Tensor) -> torch.Tensor:
|
|
202
245
|
normal0 = torch.cross(rdu_sf[:, :, 1], rdu_sf[:, :, 0], dim=1)
|
|
203
|
-
normals = normal0 / (
|
|
246
|
+
normals = normal0 / (
|
|
247
|
+
normal0.norm(dim=1, keepdim=True)
|
|
248
|
+
+ CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE
|
|
249
|
+
)
|
|
204
250
|
return normals
|
|
205
251
|
|
|
206
|
-
def _offset_points(
|
|
252
|
+
def _offset_points(
|
|
253
|
+
self, r_sf: torch.Tensor, rdu_sf: torch.Tensor, thickness: float
|
|
254
|
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
|
255
|
+
"""Offset surface points and the normals they were offset along."""
|
|
207
256
|
normals = self._surface_normals(rdu_sf=rdu_sf)
|
|
208
|
-
thickness = float(self.geometry.shell_thickness)
|
|
209
257
|
return r_sf + self.normal_sign * thickness * normals, normals
|
|
210
258
|
|
|
211
|
-
def
|
|
259
|
+
def _min_distance(self, thickness: float) -> float:
|
|
260
|
+
dmin = (
|
|
261
|
+
float(self.min_distance)
|
|
262
|
+
if self.min_distance is not None
|
|
263
|
+
else (2.0 * thickness)
|
|
264
|
+
)
|
|
265
|
+
return max(dmin, CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE)
|
|
266
|
+
|
|
267
|
+
def initialize(self, r0, rdu0, *args, part_interface=None, **kwargs) -> None:
|
|
268
|
+
"""Take the Part this constraint is evaluated for and pair its points.
|
|
269
|
+
|
|
270
|
+
The geometry updater hands over the Part it evaluates; only a
|
|
271
|
+
:class:`~morphopt.codesign.OffsetBoundaryPart` carries a
|
|
272
|
+
shell, so anything else is rejected here.
|
|
273
|
+
"""
|
|
212
274
|
super().initialize(r0=r0, rdu0=rdu0, *args, **kwargs)
|
|
275
|
+
if not isinstance(part_interface, OffsetBoundaryPart):
|
|
276
|
+
raise TypeError(
|
|
277
|
+
f"{type(self).__name__} is evaluated for one co-design Part "
|
|
278
|
+
f"(got {type(part_interface).__name__})."
|
|
279
|
+
)
|
|
280
|
+
self.shell_thickness = float(part_interface.shell_thickness)
|
|
213
281
|
|
|
214
282
|
self._neighbor_pairs = {}
|
|
215
283
|
self._neighbor_mindist = {}
|
|
216
284
|
|
|
217
|
-
|
|
285
|
+
if self.shell_thickness <= 0:
|
|
286
|
+
return
|
|
218
287
|
|
|
219
|
-
|
|
220
|
-
dmin = float(self.min_distance) if self.min_distance is not None else (2.0 * thickness)
|
|
221
|
-
dmin = max(dmin, 1e-12)
|
|
222
|
-
search_radius = max(dmin * self.search_ratio, dmin)
|
|
288
|
+
import scipy.spatial
|
|
223
289
|
|
|
224
290
|
for sf_idx in self._selected_surface_ids(len(r0)):
|
|
225
|
-
|
|
291
|
+
dmin = self._min_distance(self.shell_thickness)
|
|
292
|
+
search_radius = max(dmin * self.search_ratio, dmin)
|
|
293
|
+
|
|
294
|
+
roff, normals = self._offset_points(
|
|
295
|
+
r_sf=r0[sf_idx], rdu_sf=rdu0[sf_idx], thickness=self.shell_thickness
|
|
296
|
+
)
|
|
226
297
|
|
|
227
298
|
tree = scipy.spatial.KDTree(roff.detach().cpu().numpy())
|
|
228
|
-
pairs_np = tree.query_pairs(r=search_radius, output_type=
|
|
299
|
+
pairs_np = tree.query_pairs(r=search_radius, output_type="ndarray")
|
|
229
300
|
if pairs_np.size == 0:
|
|
230
301
|
continue
|
|
231
302
|
|
|
232
|
-
pairs = torch.from_numpy(pairs_np.T).to(
|
|
303
|
+
pairs = torch.from_numpy(pairs_np.T).to(
|
|
304
|
+
dtype=torch.int64, device=r0[sf_idx].device
|
|
305
|
+
)
|
|
233
306
|
|
|
234
307
|
dotn = (normals[pairs[0]] * normals[pairs[1]]).sum(dim=1)
|
|
235
308
|
opposition = (-dotn).clamp(min=0.0)
|
|
@@ -239,22 +312,29 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
239
312
|
self._neighbor_pairs[sf_idx] = pairs
|
|
240
313
|
self._neighbor_mindist[sf_idx] = dmin * opposition[keep]
|
|
241
314
|
|
|
242
|
-
def __call__(
|
|
315
|
+
def __call__(
|
|
316
|
+
self,
|
|
317
|
+
r: list[torch.Tensor],
|
|
318
|
+
rdu: list[torch.Tensor],
|
|
319
|
+
rdu2: list[torch.Tensor],
|
|
320
|
+
*args,
|
|
321
|
+
**kwargs,
|
|
322
|
+
) -> torch.Tensor:
|
|
243
323
|
loss = torch.zeros(1, device=r[0].device, dtype=r[0].dtype)
|
|
244
324
|
|
|
245
|
-
if float(self.geometry.shell_thickness) <= 0:
|
|
246
|
-
return loss
|
|
247
|
-
|
|
248
|
-
thickness = float(self.geometry.shell_thickness)
|
|
249
|
-
dmin = float(self.min_distance) if self.min_distance is not None else (2.0 * thickness)
|
|
250
|
-
dmin = max(dmin, 1e-12)
|
|
251
|
-
barrier_thre = max(dmin * self.barrier_thre_ratio, 1e-12)
|
|
252
|
-
|
|
253
325
|
for sf_idx in self._selected_surface_ids(len(r)):
|
|
254
326
|
pairs = self._neighbor_pairs.get(sf_idx, None)
|
|
255
327
|
if pairs is None or pairs.numel() == 0:
|
|
256
328
|
continue
|
|
257
329
|
|
|
330
|
+
thickness = self.shell_thickness
|
|
331
|
+
if thickness <= 0:
|
|
332
|
+
continue
|
|
333
|
+
barrier_thre = max(
|
|
334
|
+
self._min_distance(thickness) * self.barrier_thre_ratio,
|
|
335
|
+
CONSTANT.KERNEL.CODESIGN.GEOMETRY_TOLERANCE,
|
|
336
|
+
)
|
|
337
|
+
|
|
258
338
|
# Base surface normals (offset surface shares same normal direction)
|
|
259
339
|
normals = self._surface_normals(rdu_sf=rdu[sf_idx])
|
|
260
340
|
dotn = (normals[pairs[0]] * normals[pairs[1]]).sum(dim=1)
|
|
@@ -267,27 +347,46 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
267
347
|
pairs_n = pairs[:, mask_n]
|
|
268
348
|
dotn_n = dotn[mask_n]
|
|
269
349
|
mindist_n = self._neighbor_mindist[sf_idx][mask_n].to(
|
|
270
|
-
device=r[sf_idx].device, dtype=r[sf_idx].dtype
|
|
350
|
+
device=r[sf_idx].device, dtype=r[sf_idx].dtype
|
|
351
|
+
)
|
|
271
352
|
scaler_n0 = self.scaler[sf_idx][pairs_n[0]]
|
|
272
353
|
scaler_n1 = self.scaler[sf_idx][pairs_n[1]]
|
|
273
354
|
|
|
274
355
|
# Offset points and distance
|
|
275
|
-
roff, _ = self._offset_points(
|
|
356
|
+
roff, _ = self._offset_points(
|
|
357
|
+
r_sf=r[sf_idx], rdu_sf=rdu[sf_idx], thickness=thickness
|
|
358
|
+
)
|
|
276
359
|
delta = roff[pairs_n[0]] - roff[pairs_n[1]]
|
|
277
|
-
dist = torch.sqrt(
|
|
360
|
+
dist = torch.sqrt(
|
|
361
|
+
(delta * delta).sum(dim=1)
|
|
362
|
+
+ CONSTANT.KERNEL.CODESIGN.DISTANCE_SQUARED_TOLERANCE
|
|
363
|
+
)
|
|
278
364
|
|
|
279
365
|
violation = mindist_n - dist + barrier_thre
|
|
280
|
-
indexl, l = self.barrier_function(
|
|
366
|
+
indexl, l = self.barrier_function(
|
|
367
|
+
violation, barrier_thre, self.barrier_ratio, self.p
|
|
368
|
+
)
|
|
281
369
|
|
|
282
370
|
if indexl.numel() > 0:
|
|
283
371
|
# Smooth normal penalty (same as Distance class)
|
|
284
|
-
np_val = (
|
|
372
|
+
np_val = (
|
|
373
|
+
self.normal_max
|
|
374
|
+
- torch.clamp(dotn_n[indexl], self.normal_min, self.normal_max)
|
|
375
|
+
) / (self.normal_max - self.normal_min)
|
|
285
376
|
np_smooth = (6 * np_val**2 - 15 * np_val + 10) * np_val**3
|
|
286
377
|
|
|
287
378
|
rel_violation = (violation[indexl] / barrier_thre).clamp(min=0.0)
|
|
288
|
-
hard_boost = torch.exp(
|
|
379
|
+
hard_boost = torch.exp(
|
|
380
|
+
(self.hard_violation_beta * (rel_violation - 1.0)).clamp(
|
|
381
|
+
min=0.0,
|
|
382
|
+
max=CONSTANT.KERNEL.CODESIGN.HARD_VIOLATION_EXPONENT_MAX,
|
|
383
|
+
)
|
|
384
|
+
)
|
|
289
385
|
penalty_strong = self.penalty_scale * l * hard_boost * np_smooth
|
|
290
386
|
|
|
291
|
-
loss =
|
|
387
|
+
loss = (
|
|
388
|
+
loss
|
|
389
|
+
+ (penalty_strong * scaler_n0[indexl] * scaler_n1[indexl]).sum()
|
|
390
|
+
)
|
|
292
391
|
|
|
293
392
|
return loss
|