morphopt 3.2.1__tar.gz → 3.2.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-3.2.1 → morphopt-3.2.2}/PKG-INFO +1 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/README.md +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/pyproject.toml +1 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/__init__.py +11 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/codesign/__init__.py +6 -4
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/codesign/constraints.py +27 -2
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/codesign/feaparams.py +9 -4
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/codesign/geometry.py +9 -6
- morphopt-3.2.2/src/morphopt/optcore/__init__.py +8 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/baseobject.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/controller.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/history.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/__init__.py +1 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/baseparam.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/basefeainterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/bodyforceinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/boundaryconditioninterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/contactinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/coupleinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/pointinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/pressureinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/referencepointinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/springinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feaparams.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/geometry.py +0 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/__init__.py +11 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/basematerialinterface.py +69 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/homogeneousmaterial.py +21 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materialinterface/materialmodels.py +111 -0
- morphopt-3.2.2/src/morphopt/optcore/modelparams/materials.py +175 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/params.py +5 -7
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/objfunc.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/solver.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/updaters.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/__init__.py +3 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/geometryinterfaces/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/geometryparams.py +32 -18
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/basefuncs.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/boundarys.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/surfacefairness.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/volumemaximization.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objfunc.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/update_geometry.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/__init__.py +4 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/objectivefuncs/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/objectivefuncs/basefuncs.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/objectivefuncs/boundarys.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/objectivefuncs/densityfield.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/objectivefuncs/sensitivity.py +0 -0
- morphopt-3.2.2/src/morphopt/simp/objectivefuncs/volfrac.py +87 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/simpmaterial.py +203 -151
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/solver.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/simp/update_material.py +36 -25
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/taskoptmization.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/codegen/generator.py +139 -51
- morphopt-3.2.2/src/morphopt/ui/model/__init__.py +20 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/model/problem.py +123 -22
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/model/schemas.py +87 -41
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/base.py +23 -3
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/codesign.py +23 -11
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/shapeopt.py +6 -2
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/simp.py +11 -6
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/editor.py +30 -4
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/model_tree.py +86 -6
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/values.py +1 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/viewer.py +1 -2
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/workbench.py +12 -8
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/utils/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/utils/gradient_check.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/utils/history_read.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/PKG-INFO +1 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/SOURCES.txt +4 -1
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/dependency_links.txt +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/requires.txt +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/top_level.txt +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/tests/test_fixedGeometry.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/tests/test_path.py +0 -0
- morphopt-3.2.1/src/morphopt/codesign/material.py +0 -53
- morphopt-3.2.1/src/morphopt/optcore/__init__.py +0 -4
- morphopt-3.2.1/src/morphopt/optcore/modelparams/materials.py +0 -119
- morphopt-3.2.1/src/morphopt/simp/objectivefuncs/volfrac.py +0 -47
- morphopt-3.2.1/src/morphopt/ui/model/__init__.py +0 -16
- {morphopt-3.2.1 → morphopt-3.2.2}/setup.cfg +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/codesign/params.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/opt_runner.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/geometryinterfaces/basesurfaceinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/geometryinterfaces/bspsurfaceinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/geometryinterfaces/cpgeosurfaceinterface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/distancesurface.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/shapeopt/objectivefuncs/shapederivative.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/__main__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/app.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/codegen/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/i18n.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/launcher.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/mainwindow.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/model/loaders.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/observe_panel.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/schemes/snippets.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/__init__.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/code_completion.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/codeeditor.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/objective_editor.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/observation_pages.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/param_form.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/solver_editor.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/stepmatrix.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/template_insert_dialog.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/torchfea_model_editor.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/ui/widgets/updater_editor.py +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt.egg-info/entry_points.txt +0 -0
- {morphopt-3.2.1 → morphopt-3.2.2}/tests/test_ui.py +0 -0
|
File without changes
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
A differentiable structural optimization framework that eliminates manual sensitivity derivation by fusing 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.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
# Torch and TorchFEA use GNU OpenMP in this environment. Set MKL's matching
|
|
6
|
+
# threading layer before importing any module that can load NumPy or Torch.
|
|
7
|
+
import os as __os
|
|
8
|
+
import sys as __sys
|
|
9
|
+
|
|
10
|
+
if __sys.platform.startswith("linux"):
|
|
11
|
+
__os.environ["MKL_THREADING_LAYER"] = "GNU"
|
|
5
12
|
|
|
6
13
|
# region: Logging Configuration
|
|
7
14
|
import logging as __logging
|
|
@@ -57,7 +64,10 @@ def enable_logging(level=__logging.INFO, log_file=None, file_log_level=__logging
|
|
|
57
64
|
|
|
58
65
|
# region optcore imports
|
|
59
66
|
from .optcore.controller import Controller
|
|
60
|
-
from .optcore.modelparams import
|
|
67
|
+
from .optcore.modelparams import (
|
|
68
|
+
FEAParams, FixedGeometryINP, FixedGeometryTorchFEA, FixedGeometry,
|
|
69
|
+
MaterialsParams, Params,
|
|
70
|
+
)
|
|
61
71
|
from .optcore.solver import Solver
|
|
62
72
|
from .optcore.modelparams import Params
|
|
63
73
|
from .optcore.updaters import Updaters
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
from .material import CodesignMaterials
|
|
2
1
|
from .geometry import CodesignGeometry
|
|
3
2
|
from .constraints import InwardCurvatureRadius, OffsetSurfaceMinThickness
|
|
4
3
|
from .feaparams import CodesignFEAParams
|
|
5
4
|
from .params import Params
|
|
6
|
-
from ..optcore import
|
|
5
|
+
from ..optcore import (
|
|
6
|
+
MaterialsParams, Solver, Updaters,
|
|
7
|
+
)
|
|
7
8
|
from ..shapeopt import GeometryParams, UpdaterGeometries, ObjectiveFunction
|
|
8
9
|
from ..simp import UpdaterMaterials
|
|
10
|
+
from ..simp import SIMP_BSPFieldMaterials
|
|
9
11
|
|
|
10
|
-
def plot_geometry_and_materials(geometry: CodesignGeometry, materials:
|
|
12
|
+
def plot_geometry_and_materials(geometry: CodesignGeometry, materials: MaterialsParams):
|
|
11
13
|
import pyvista as pv
|
|
12
14
|
plotter = pv.Plotter(window_size=(1400, 900))
|
|
13
15
|
plotter.set_background('white')
|
|
@@ -15,4 +17,4 @@ def plot_geometry_and_materials(geometry: CodesignGeometry, materials: CodesignM
|
|
|
15
17
|
plotter = materials.plot(plotter=plotter)
|
|
16
18
|
geometry.plot(plotter=plotter, opacity=[0.0, 1.0])
|
|
17
19
|
|
|
18
|
-
plotter.show()
|
|
20
|
+
plotter.show()
|
|
@@ -49,17 +49,28 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
49
49
|
super().__init__()
|
|
50
50
|
|
|
51
51
|
self.geometry = geometry
|
|
52
|
+
"""Stores the geometry used by InwardCurvatureRadius."""
|
|
52
53
|
self.surface_start = int(surface_start)
|
|
54
|
+
"""Stores the surface start used by InwardCurvatureRadius."""
|
|
53
55
|
self.surface_ids = None if surface_ids is None else [int(i) for i in surface_ids]
|
|
56
|
+
"""Stores the surface ids used by InwardCurvatureRadius."""
|
|
54
57
|
|
|
55
58
|
self.margin = margin
|
|
59
|
+
"""Stores the margin used by InwardCurvatureRadius."""
|
|
56
60
|
self.margin_ratio = float(margin_ratio)
|
|
61
|
+
"""Stores the margin ratio used by InwardCurvatureRadius."""
|
|
57
62
|
self.barrier_thre_ratio = float(barrier_thre_ratio)
|
|
63
|
+
"""Stores the barrier thre ratio used by InwardCurvatureRadius."""
|
|
58
64
|
self.barrier_ratio = float(barrier_ratio)
|
|
65
|
+
"""Stores the barrier ratio used by InwardCurvatureRadius."""
|
|
59
66
|
self.p = int(p)
|
|
67
|
+
"""Stores the p used by InwardCurvatureRadius."""
|
|
60
68
|
self.penalty_scale = float(penalty_scale)
|
|
69
|
+
"""Stores the penalty scale used by InwardCurvatureRadius."""
|
|
61
70
|
self.hard_violation_beta = float(hard_violation_beta)
|
|
71
|
+
"""Stores the hard violation beta used by InwardCurvatureRadius."""
|
|
62
72
|
self.normal_sign = 1.0 if normal_sign >= 0 else -1.0
|
|
73
|
+
"""Stores the normal sign used by InwardCurvatureRadius."""
|
|
63
74
|
|
|
64
75
|
@staticmethod
|
|
65
76
|
def _principal_curvatures(rdu: torch.Tensor, rdu2: torch.Tensor, eps: float = 1e-12) -> tuple[torch.Tensor, torch.Tensor]:
|
|
@@ -119,7 +130,6 @@ class InwardCurvatureRadius(BaseConstraints):
|
|
|
119
130
|
|
|
120
131
|
return loss
|
|
121
132
|
|
|
122
|
-
|
|
123
133
|
class OffsetSurfaceMinThickness(BaseConstraints):
|
|
124
134
|
"""
|
|
125
135
|
Enforce a minimum distance on the offset surface to reduce self-intersection risk.
|
|
@@ -148,23 +158,39 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
148
158
|
super().__init__()
|
|
149
159
|
|
|
150
160
|
self.geometry = geometry
|
|
161
|
+
"""Stores the geometry used by OffsetSurfaceMinThickness."""
|
|
151
162
|
self.surface_start = int(surface_start)
|
|
163
|
+
"""Stores the surface start used by OffsetSurfaceMinThickness."""
|
|
152
164
|
self.surface_ids = None if surface_ids is None else [int(i) for i in surface_ids]
|
|
165
|
+
"""Stores the surface ids used by OffsetSurfaceMinThickness."""
|
|
153
166
|
|
|
154
167
|
self.min_distance = min_distance
|
|
168
|
+
"""Stores the min distance used by OffsetSurfaceMinThickness."""
|
|
155
169
|
self.search_ratio = float(search_ratio)
|
|
170
|
+
"""Stores the search ratio used by OffsetSurfaceMinThickness."""
|
|
156
171
|
self.barrier_thre_ratio = float(barrier_thre_ratio)
|
|
172
|
+
"""Stores the barrier thre ratio used by OffsetSurfaceMinThickness."""
|
|
157
173
|
self.barrier_ratio = float(barrier_ratio)
|
|
174
|
+
"""Stores the barrier ratio used by OffsetSurfaceMinThickness."""
|
|
158
175
|
self.p = int(p)
|
|
176
|
+
"""Stores the p used by OffsetSurfaceMinThickness."""
|
|
159
177
|
self.penalty_scale = float(penalty_scale)
|
|
178
|
+
"""Stores the penalty scale used by OffsetSurfaceMinThickness."""
|
|
160
179
|
self.hard_violation_beta = float(hard_violation_beta)
|
|
180
|
+
"""Stores the hard violation beta used by OffsetSurfaceMinThickness."""
|
|
161
181
|
self.normal_sign = 1.0 if normal_sign >= 0 else -1.0
|
|
182
|
+
"""Stores the normal sign used by OffsetSurfaceMinThickness."""
|
|
162
183
|
self.normal_opposition_thre = float(normal_opposition_thre)
|
|
184
|
+
"""Stores the normal opposition thre used by OffsetSurfaceMinThickness."""
|
|
163
185
|
self.normal_min = float(normal_min)
|
|
186
|
+
"""Stores the normal min used by OffsetSurfaceMinThickness."""
|
|
164
187
|
self.normal_max = float(normal_max)
|
|
188
|
+
"""Stores the normal max used by OffsetSurfaceMinThickness."""
|
|
165
189
|
|
|
166
190
|
self._neighbor_pairs: dict[int, torch.Tensor] = {}
|
|
191
|
+
"""Stores the neighbor pairs used by OffsetSurfaceMinThickness."""
|
|
167
192
|
self._neighbor_mindist: dict[int, torch.Tensor] = {}
|
|
193
|
+
"""Stores the neighbor mindist used by OffsetSurfaceMinThickness."""
|
|
168
194
|
|
|
169
195
|
def _selected_surface_ids(self, n_surface: int) -> list[int]:
|
|
170
196
|
if self.surface_ids is None:
|
|
@@ -265,4 +291,3 @@ class OffsetSurfaceMinThickness(BaseConstraints):
|
|
|
265
291
|
loss = loss + (penalty_strong * scaler_n0[indexl] * scaler_n1[indexl]).sum()
|
|
266
292
|
|
|
267
293
|
return loss
|
|
268
|
-
|
|
@@ -4,6 +4,7 @@ import torch
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
6
|
import torchfea
|
|
7
|
+
import morphopt
|
|
7
8
|
from .. import FEAParams
|
|
8
9
|
import bspmap
|
|
9
10
|
|
|
@@ -15,7 +16,11 @@ class CodesignFEAParams(FEAParams):
|
|
|
15
16
|
|
|
16
17
|
def create_fea(self, assembly: torchfea.Assembly) -> torchfea.FEAController:
|
|
17
18
|
fe = super().create_fea(assembly=assembly)
|
|
18
|
-
|
|
19
|
+
geometry = getattr(getattr(morphopt, "controller", None), "params", None)
|
|
20
|
+
geometry = getattr(geometry, "geometry", None)
|
|
21
|
+
part_name = getattr(geometry, "part_name", "final_model")
|
|
22
|
+
instance_name = getattr(geometry, "instance_name", "final_model")
|
|
23
|
+
fe_part = fe.assembly.get_part(part_name)
|
|
19
24
|
|
|
20
25
|
if 'C3D6' in fe_part.elems:
|
|
21
26
|
element_shell = fe_part.elems['C3D6']
|
|
@@ -40,10 +45,10 @@ class CodesignFEAParams(FEAParams):
|
|
|
40
45
|
)
|
|
41
46
|
surfcenter = surfnodes.mean(dim=1)
|
|
42
47
|
|
|
43
|
-
fe.assembly.get_instance(
|
|
48
|
+
fe.assembly.get_instance(instance_name).exterior_surface = 'surface_1_offset'
|
|
44
49
|
|
|
45
|
-
mesh_1all = fe.assembly.get_instance(
|
|
46
|
-
mesh_1offset = fe.assembly.get_instance(
|
|
50
|
+
mesh_1all = fe.assembly.get_instance(instance_name).get_mesh(surf_name='surface_1_All')
|
|
51
|
+
mesh_1offset = fe.assembly.get_instance(instance_name).get_mesh(surf_name='surface_1_offset')
|
|
47
52
|
|
|
48
53
|
import morphopt
|
|
49
54
|
normal_cpgeo = morphopt.controller.params.geometry.surface_list[1].get_normals(torch.from_numpy(morphopt.controller.params.geometry.surface_list[1].surf_node_uv).to(torch.get_default_device()))
|
|
@@ -6,10 +6,6 @@ import torchfea
|
|
|
6
6
|
|
|
7
7
|
class CodesignGeometry(GeometryParams):
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
9
|
def __init__(self,
|
|
14
10
|
fea_seed_size: float,
|
|
15
11
|
mesh_order: int = 1,
|
|
@@ -50,12 +46,19 @@ class CodesignGeometry(GeometryParams):
|
|
|
50
46
|
"""Element-id offset for the shell block (0-based)."""
|
|
51
47
|
|
|
52
48
|
self._reinit_opt_steps: int = 100
|
|
49
|
+
"""Stores the reinit opt steps used by CodesignGeometry."""
|
|
53
50
|
self._reinit_opt_lr: float = 5e-3
|
|
51
|
+
"""Stores the reinit opt lr used by CodesignGeometry."""
|
|
54
52
|
self._reinit_opt_curvature_weight: float = 1e2
|
|
53
|
+
"""Stores the reinit opt curvature weight used by CodesignGeometry."""
|
|
55
54
|
self._reinit_opt_shape_weight: float = 1e2
|
|
55
|
+
"""Stores the reinit opt shape weight used by CodesignGeometry."""
|
|
56
56
|
self._reinit_opt_curvature_margin_ratio: float = 0.25
|
|
57
|
+
"""Stores the reinit opt curvature margin ratio used by CodesignGeometry."""
|
|
57
58
|
self._reinit_opt_inward_sign: float = 1.0
|
|
59
|
+
"""Stores the reinit opt inward sign used by CodesignGeometry."""
|
|
58
60
|
self._reinit_opt_accept_only_improve: bool = True
|
|
61
|
+
"""Stores the reinit opt accept only improve used by CodesignGeometry."""
|
|
59
62
|
|
|
60
63
|
# def reinitialize(self, iteration):
|
|
61
64
|
# super().reinitialize(iteration)
|
|
@@ -334,7 +337,7 @@ class CodesignGeometry(GeometryParams):
|
|
|
334
337
|
if len(self._node_idx) == 0 or self._tri_local is None:
|
|
335
338
|
return
|
|
336
339
|
|
|
337
|
-
part = assembly.get_part(
|
|
340
|
+
part = assembly.get_part(self.part_name)
|
|
338
341
|
|
|
339
342
|
nodes = part.nodes.clone()
|
|
340
343
|
base_ids_t = torch.as_tensor(self._node_idx[0], dtype=torch.long, device=nodes.device)
|
|
@@ -356,4 +359,4 @@ class CodesignGeometry(GeometryParams):
|
|
|
356
359
|
|
|
357
360
|
def plot(self, plotter=None, opacity = None, meshes=None):
|
|
358
361
|
opacity = [0.0 if i == 0 else 1.0 for i in range(self.num_surface)]
|
|
359
|
-
return super().plot(plotter, opacity, meshes)
|
|
362
|
+
return super().plot(plotter, opacity, meshes)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .modelparams import (
|
|
2
|
+
Params, BaseGeometry, FEAParams,
|
|
3
|
+
MaterialsParams, BaseParams,
|
|
4
|
+
FixedGeometryINP, FixedGeometryTorchFEA, FixedGeometry,
|
|
5
|
+
)
|
|
6
|
+
from .updaters import BaseUpdater, Updaters
|
|
7
|
+
from .solver import Solver
|
|
8
|
+
from .objfunc import ObjectiveFunction
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .geometry import FixedGeometryINP, FixedGeometryTorchFEA, FixedGeometry, BaseGeometry
|
|
2
2
|
from .feaparams import FEAParams
|
|
3
|
-
from .materials import
|
|
3
|
+
from .materials import MaterialsParams
|
|
4
4
|
from .params import Params
|
|
5
5
|
from .baseparam import BaseParams
|
|
File without changes
|
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/basefeainterface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/contactinterface.py
RENAMED
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/coupleinterface.py
RENAMED
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/pointinterface.py
RENAMED
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/pressureinterface.py
RENAMED
|
File without changes
|
|
File without changes
|
{morphopt-3.2.1 → morphopt-3.2.2}/src/morphopt/optcore/modelparams/feainterface/springinterface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Material assignment interfaces."""
|
|
2
|
+
|
|
3
|
+
from .basematerialinterface import BaseMaterialInterface
|
|
4
|
+
from .homogeneousmaterial import HomogeneousMaterial
|
|
5
|
+
from .materialmodels import MaterialModels
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"BaseMaterialInterface",
|
|
9
|
+
"HomogeneousMaterial",
|
|
10
|
+
"MaterialModels",
|
|
11
|
+
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Base class for material assignments to TorchFEA parts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import torch
|
|
6
|
+
import torchfea
|
|
7
|
+
|
|
8
|
+
from ..baseparam import BaseParams
|
|
9
|
+
from .materialmodels import MaterialModels
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseMaterialInterface(BaseParams):
|
|
13
|
+
"""Assign one material definition to elements in one Part.
|
|
14
|
+
|
|
15
|
+
``elementname`` may be empty. In that case the interface is applied to
|
|
16
|
+
every element family in ``part_name``.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .materialmodels import MaterialModels as materialmodels
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
part_name: str,
|
|
24
|
+
material_parameters: MaterialModels.MaterialParameters,
|
|
25
|
+
elementname: str = "",
|
|
26
|
+
density: float = 0.0,
|
|
27
|
+
) -> None:
|
|
28
|
+
super().__init__()
|
|
29
|
+
self.part_name = str(part_name or "").strip()
|
|
30
|
+
if not self.part_name:
|
|
31
|
+
raise ValueError("part_name cannot be empty.")
|
|
32
|
+
self.elementname = str(elementname or "").strip()
|
|
33
|
+
self.material_parameters: MaterialModels.MaterialParameters = material_parameters
|
|
34
|
+
self._density: float = float(density)
|
|
35
|
+
self._name: str = ""
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def density(self) -> float:
|
|
39
|
+
"""Return the mass density assigned to the target elements."""
|
|
40
|
+
return self._density
|
|
41
|
+
|
|
42
|
+
@density.setter
|
|
43
|
+
def density(self, value: float) -> None:
|
|
44
|
+
"""Set the mass density assigned to the target elements."""
|
|
45
|
+
self._density = float(value)
|
|
46
|
+
|
|
47
|
+
def target_elements(
|
|
48
|
+
self,
|
|
49
|
+
assembly: torchfea.Assembly,
|
|
50
|
+
) -> list[tuple[str, torchfea.elements.Element_3D]]:
|
|
51
|
+
"""Return the selected element families from the target Part."""
|
|
52
|
+
part = assembly.get_part(self.part_name)
|
|
53
|
+
if self.elementname:
|
|
54
|
+
if self.elementname not in part.elems:
|
|
55
|
+
raise KeyError(
|
|
56
|
+
f"Element {self.elementname!r} does not exist on Part "
|
|
57
|
+
f"{self.part_name!r}.")
|
|
58
|
+
return [(self.elementname, part.elems[self.elementname])]
|
|
59
|
+
if not part.elems:
|
|
60
|
+
raise ValueError(f"Part {self.part_name!r} contains no elements.")
|
|
61
|
+
return list(part.elems.items())
|
|
62
|
+
|
|
63
|
+
def set_materials(self, fe: torchfea.FEAController) -> None:
|
|
64
|
+
"""Assign this interface to its target elements."""
|
|
65
|
+
raise NotImplementedError
|
|
66
|
+
|
|
67
|
+
def get_design_values(self) -> torch.Tensor:
|
|
68
|
+
"""Return live design values for a designable material interface."""
|
|
69
|
+
return torch.zeros(0)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Uniform material assignment interface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import torchfea
|
|
6
|
+
|
|
7
|
+
from .basematerialinterface import BaseMaterialInterface
|
|
8
|
+
from .materialmodels import MaterialModels
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class HomogeneousMaterial(BaseMaterialInterface):
|
|
12
|
+
"""Assign one uniform TorchFEA material to a Part."""
|
|
13
|
+
|
|
14
|
+
def set_materials(self, fe: torchfea.FEAController) -> None:
|
|
15
|
+
"""Assign the uniform material and density to target elements."""
|
|
16
|
+
for _name, elements in self.target_elements(fe.assembly):
|
|
17
|
+
elements.delete_material()
|
|
18
|
+
elements.set_materials(MaterialModels.create_material(
|
|
19
|
+
material_parameters=self.material_parameters,
|
|
20
|
+
))
|
|
21
|
+
elements.density = self.density
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""TorchFEA material models exposed by :class:`MaterialsParams`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, fields
|
|
6
|
+
from typing import ClassVar
|
|
7
|
+
|
|
8
|
+
import torchfea
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MaterialModels:
|
|
12
|
+
"""Material parameter types and their TorchFEA material classes."""
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class MaterialParameters:
|
|
16
|
+
"""Base type for all material parameter objects."""
|
|
17
|
+
|
|
18
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]]
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class LinearElasticParams(MaterialParameters):
|
|
22
|
+
"""Parameters for ``torchfea.materials.LinearElastic``."""
|
|
23
|
+
|
|
24
|
+
E: float
|
|
25
|
+
nu: float
|
|
26
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
27
|
+
torchfea.materials.LinearElastic
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class NeoHookeanParams(MaterialParameters):
|
|
31
|
+
"""Parameters for ``torchfea.materials.NeoHookean``."""
|
|
32
|
+
|
|
33
|
+
mu: float
|
|
34
|
+
kappa: float
|
|
35
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
36
|
+
torchfea.materials.NeoHookean
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class NeoHookeanLnJParams(MaterialParameters):
|
|
40
|
+
"""Parameters for ``torchfea.materials.NeoHookeanLnJ``."""
|
|
41
|
+
|
|
42
|
+
mu: float
|
|
43
|
+
kappa: float
|
|
44
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
45
|
+
torchfea.materials.NeoHookeanLnJ
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class MooneyRivlinParams(MaterialParameters):
|
|
49
|
+
"""Parameters for ``torchfea.materials.MooneyRivlin``."""
|
|
50
|
+
|
|
51
|
+
c10: float
|
|
52
|
+
c01: float
|
|
53
|
+
kappa: float
|
|
54
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
55
|
+
torchfea.materials.MooneyRivlin
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class YeohParams(MaterialParameters):
|
|
59
|
+
"""Parameters for ``torchfea.materials.Yeoh``."""
|
|
60
|
+
|
|
61
|
+
c1: float
|
|
62
|
+
c2: float
|
|
63
|
+
c3: float
|
|
64
|
+
kappa: float
|
|
65
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
66
|
+
torchfea.materials.Yeoh
|
|
67
|
+
|
|
68
|
+
@dataclass(frozen=True)
|
|
69
|
+
class GentParams(MaterialParameters):
|
|
70
|
+
"""Parameters for ``torchfea.materials.Gent``."""
|
|
71
|
+
|
|
72
|
+
mu: float
|
|
73
|
+
Jm: float
|
|
74
|
+
kappa: float
|
|
75
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
76
|
+
torchfea.materials.Gent
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class ArrudaBoyceParams(MaterialParameters):
|
|
80
|
+
"""Parameters for ``torchfea.materials.ArrudaBoyce``."""
|
|
81
|
+
|
|
82
|
+
mu: float
|
|
83
|
+
N: float
|
|
84
|
+
kappa: float
|
|
85
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
86
|
+
torchfea.materials.ArrudaBoyce
|
|
87
|
+
|
|
88
|
+
@dataclass(frozen=True)
|
|
89
|
+
class OgdenParams(MaterialParameters):
|
|
90
|
+
"""Parameters for ``torchfea.materials.Ogden``."""
|
|
91
|
+
|
|
92
|
+
mu: float
|
|
93
|
+
alpha: float | list[float]
|
|
94
|
+
kappa: float
|
|
95
|
+
material_class: ClassVar[type[torchfea.materials.Materials_Base]] = \
|
|
96
|
+
torchfea.materials.Ogden
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def create_material(
|
|
100
|
+
cls,
|
|
101
|
+
material_parameters: MaterialParameters,
|
|
102
|
+
) -> torchfea.materials.Materials_Base:
|
|
103
|
+
"""Create a TorchFEA material from its typed parameter object."""
|
|
104
|
+
if not isinstance(material_parameters, cls.MaterialParameters):
|
|
105
|
+
raise TypeError(
|
|
106
|
+
"material_parameters must be a MaterialModels parameter object.")
|
|
107
|
+
parameters = {
|
|
108
|
+
field.name: getattr(material_parameters, field.name)
|
|
109
|
+
for field in fields(material_parameters)
|
|
110
|
+
}
|
|
111
|
+
return material_parameters.material_class(**parameters)
|