Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/_static/img/problems/thermoelastic3d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ introduction/api
problems/airfoil
problems/beams2d
problems/thermoelastic2d
problems/thermoelastic3d
problems/photonics2d
problems/power_electronics
problems/heatconduction
Expand Down
55 changes: 55 additions & 0 deletions docs/problems/thermoelastic3d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Thermoelastic3D

```{problem:table}
:lead: Gabriel Apaza @gapaza
```


## Motivation
As articulated in their respective sections, both the Beams2D and HeatConduction2D problems found in the EngiBench library are fundamental engineering design problems that have historically served as benchmarks for the development and testing of optimization methods.
While their relevance is supported by needs in real engineering design scenarios (aerospace, automotive, consumer electronics, etc...), their mono-domain nature ignores the reality that coupling between domains exists, and should be accounted for in scenarios where performance in one domain significantly impacts performance in another.
To address this distinction, a multi-physics topology optimization problem is developed that captures the coupling between structural and thermal domains in three dimensions.

## Design space
This multi-physics topology optimization problem is governed by linear elasticity and steady-state heat conduction with a one-way coupling from the thermal domain to the elastic domain.
The problem is defined over a cube 3D domain, where load elements and support elements are placed along the boundary to define a unique elastic condition.
Similarly, heatsink elements are placed along the boundary to define a unique thermal condition.
The design space is then defined by a 3D array representing density values (parameterized by DesignSpace = [0,1]^{nelx x nely x nelz}, where nelx, nely, and nelz denote the x, y, and z dimensions respectively).

## Objectives
The objective of this problem is to minimize total compliance C under a volume fraction constraint V by placing a thermally conductive material.
Total compliance is defined as the sum of thermal compliance and structural compliance.

## Conditions

```{problem:conditions}
```

## Simulator
The simulation code is based on a Python adaptation of the popular 88-line topology optimization code, modified to handle the thermal domain in addition to thermal-elastic coupling.
Optimization is conducted by reformulating the integer optimization problem as a continuous one (leveraging a SIMP approach), where a density filtering approach is used to prevent checkerboard-like artifacts.
The optimization process itself operates by calculating the sensitivities of the design variables with respect to total compliance (done efficiently using the Adjoint method), calculating the sensitivities of the design variables with respect to the constraint value, and then updating the design variables by solving a convex-linear subproblem and taking a small step (using the method of moving asymptotes).
The optimization loop terminates when either an upper bound of the number of iterations has been reached or if the magnitude of the gradient update is below some threshold.

## Dataset
The dataset linked to this problem is on huggingface [Hugging Face Datasets Hub](https://huggingface.co/datasets/IDEALLab/thermoelastic_3d_v0).
This dataset contains a set of 100 optimized thermoelastic designs in a 16x16x16 domain, where each design is optimized for a unique set of conditions.
Each datapoint's conditions are randomly generated by arbitrarily placing: a single loaded element along the bottom boundary, two fixed elements (fixed in the x, y, and z direction) along the left and top boundary, and heatsink elements along the right boundary.
Furthermore, values for the volume fraction constraint are randomly selected in the range $[0.2, 0.5]$.

Relevant datapoint fields include:
- `optimal_design`: An optimized design for the set of boundary conditions
- `fixed_elements`: Encodes a binary NxNxN matrix of the structurally fixed elements in the domain.
- `force_elements_x`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the x-direction.
- `force_elements_y`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the y-direction.
- `force_elements_z`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the z-direction.
- `heatsink_elements`: Encodes a binary NxNxN matrix specifying elements that have a heat sink.
- `volume_fraction`: The volume fraction value of the optimized design
- `structural_compliance`: The structural compliance of the optimized design
- `thermal_compliance`: The thermal compliance of the optimized design
- `nelx`: The number of elements in the x-direction
- `nely`: The number of elements in the y-direction
- `nelz`: The number of elements in the z-direction
- `volfrac`: The volume fraction target of the optimized design
- `rmin`: The filter size used in the optimization routine
- `weight`: The domain weighting used in the optimization routine
70 changes: 9 additions & 61 deletions engibench/problems/thermoelastic3d/v0.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,68 +35,9 @@


class ThermoElastic3D(Problem[npt.NDArray]):
r"""Truss 3D integer optimization problem.
"""Truss 3D integer optimization problem.

## Problem Description
This is 3D topology optimization problem for minimizing weakly coupled thermo-elastic compliance subject to boundary conditions and a volume fraction constraint.

## Motivation
As articulated in their respective sections, both the Beams2D and HeatConduction2D problems found in the EngiBench library are fundamental engineering design problems that have historically served as benchmarks for the development and testing of optimization methods.
While their relevance is supported by needs in real engineering design scenarios (aerospace, automotive, consumer electronics, etc...), their mono-domain nature ignores the reality that coupling between domains exists, and should be accounted for in scenarios where performance in one domain significantly impacts performance in another.
To address this distinction, a multi-physics topology optimization problem is developed that captures the coupling between structural and thermal domains in three dimensions.

## Design space
This multi-physics topology optimization problem is governed by linear elasticity and steady-state heat conduction with a one-way coupling from the thermal domain to the elastic domain.
The problem is defined over a cube 3D domain, where load elements and support elements are placed along the boundary to define a unique elastic condition.
Similarly, heatsink elements are placed along the boundary to define a unique thermal condition.
The design space is then defined by a 3D array representing density values (parameterized by DesignSpace = [0,1]^{nelx x nely x nelz}, where nelx, nely, and nelz denote the x, y, and z dimensions respectively).

## Objectives
The objective of this problem is to minimize total compliance C under a volume fraction constraint V by placing a thermally conductive material.
Total compliance is defined as the sum of thermal compliance and structural compliance.

## Conditions
Problem conditions are defined by creating a python dict with the following info:
- `fixed_elements`: Encodes a binary NxNxN matrix of the structurally fixed elements in the domain.
- `force_elements_x`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the x-direction.
- `force_elements_y`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the y-direction.
- `force_elements_z`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the z-direction.
- `heatsink_elements`: Encodes a binary NxNxN matrix specifying elements that have a heat sink.
- `volfrac`: Encodes the target volume fraction for the volume fraction constraint.
- `rmin`: Encodes the filter size used in the optimization routine.
- `weight`: Allows one to control which objective is optimized for. 1.0 Is pure structural optimization, while 0.0 is pure thermal optimization.

## Simulator
The simulation code is based on a Python adaptation of the popular 88-line topology optimization code, modified to handle the thermal domain in addition to thermal-elastic coupling.
Optimization is conducted by reformulating the integer optimization problem as a continuous one (leveraging a SIMP approach), where a density filtering approach is used to prevent checkerboard-like artifacts.
The optimization process itself operates by calculating the sensitivities of the design variables with respect to total compliance (done efficiently using the Adjoint method), calculating the sensitivities of the design variables with respect to the constraint value, and then updating the design variables by solving a convex-linear subproblem and taking a small step (using the method of moving asymptotes).
The optimization loop terminates when either an upper bound of the number of iterations has been reached or if the magnitude of the gradient update is below some threshold.

## Dataset
The dataset linked to this problem is on huggingface [Hugging Face Datasets Hub](https://huggingface.co/datasets/IDEALLab/thermoelastic_3d_v0).
This dataset contains a set of 100 optimized thermoelastic designs in a 16x16x16 domain, where each design is optimized for a unique set of conditions.
Each datapoint's conditions are randomly generated by arbitrarily placing: a single loaded element along the bottom boundary, two fixed elements (fixed in the x, y, and z direction) along the left and top boundary, and heatsink elements along the right boundary.
Furthermore, values for the volume fraction constraint are randomly selected in the range $[0.2, 0.5]$.

Relevant datapoint fields include:
- `optimal_design`: An optimized design for the set of boundary conditions
- `fixed_elements`: Encodes a binary NxNxN matrix of the structurally fixed elements in the domain.
- `force_elements_x`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the x-direction.
- `force_elements_y`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the y-direction.
- `force_elements_z`: Encodes a binary NxNxN matrix specifying elements that have a structural load in the z-direction.
- `heatsink_elements`: Encodes a binary NxNxN matrix specifying elements that have a heat sink.
- `volume_fraction`: The volume fraction value of the optimized design
- `structural_compliance`: The structural compliance of the optimized design
- `thermal_compliance`: The thermal compliance of the optimized design
- `nelx`: The number of elements in the x-direction
- `nely`: The number of elements in the y-direction
- `nelz`: The number of elements in the z-direction
- `volfrac`: The volume fraction target of the optimized design
- `rmin`: The filter size used in the optimization routine
- `weight`: The domain weighting used in the optimization routine

## Lead
Gabriel Apaza @gapaza
"""

version = 0
Expand All @@ -113,27 +54,34 @@ class Conditions:
fixed_elements: Annotated[npt.NDArray[np.int64], bounded(lower=0.0, upper=1.0).category(THEORY)] = field(
default_factory=lambda: FIXED_ELEMENTS
)
"""Binary NxNxN array of the structurally fixed elements in the domain"""
force_elements_x: Annotated[npt.NDArray[np.int64], bounded(lower=0.0, upper=1.0).category(THEORY)] = field(
default_factory=lambda: FORCE_ELEMENTS_X
)
"""Binary NxNxN array specifying elements that have a structural load in the x-direction"""
force_elements_y: Annotated[npt.NDArray[np.int64], bounded(lower=0.0, upper=1.0).category(THEORY)] = field(
default_factory=lambda: FORCE_ELEMENTS_Y
)
"""Binary NxNxN array specifying elements that have a structural load in the y-direction"""
force_elements_z: Annotated[npt.NDArray[np.int64], bounded(lower=0.0, upper=1.0).category(THEORY)] = field(
default_factory=lambda: FORCE_ELEMENTS_Z
)
"""Binary NxNxN array specifying elements that have a structural load in the z-direction"""
heatsink_elements: Annotated[npt.NDArray[np.int64], bounded(lower=0.0, upper=1.0).category(THEORY)] = field(
default_factory=lambda: HEATSINK_ELEMENTS
)
"""Binary NxNxN array specifying elements that have a heat sink"""
volfrac: Annotated[float, bounded(lower=0.0, upper=1.0).category(THEORY)] = 0.3
"""Target volume fraction for the volume fraction constraint"""
rmin: Annotated[
float, bounded(lower=1.0).category(THEORY), bounded(lower=0.0, upper=3.0).warning().category(IMPL)
] = 1.5
"""Filter size used in the optimization routine"""
penal: Annotated[
float, bounded(lower=1.0).category(THEORY), bounded(lower=0.0, upper=10.0).warning().category(IMPL)
] = 3.0
weight: Annotated[float, bounded(lower=0.0, upper=1.0).category(THEORY)] = 0.5
"""1.0 for pure structural, 0.0 for pure thermal"""
"""Control which objective is optimized for. 1.0 is pure structural optimization, while 0.0 is pure thermal optimization"""

conditions = Conditions()
design_space = spaces.Box(low=0.0, high=1.0, shape=(NELX, NELY, NELZ), dtype=np.float32)
Expand Down
Loading