forked from yaugenst/tofea
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sturges.py
81 lines (59 loc) · 1.62 KB
/
sturges.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
import autograd.numpy as np
import matplotlib.pyplot as plt
import nlopt
from autograd import value_and_grad
from tofea.fea2d import FEA2D_T
from tofea.topopt_helpers import simp_parametrization
max_its = 20
volfrac = 0.4
sigma = 0.5
shape = (100, 100)
nelx, nely = shape
cmin, cmax = 1.0, 1e6
fixed = np.zeros((nelx + 1, nely + 1), dtype="?")
load = np.zeros_like(fixed)
fixed[40:60, -1] = 1
load[:, :-10] = 1
fem = FEA2D_T(fixed)
parametrization = simp_parametrization(shape, sigma, cmin, cmax)
x0 = np.full(shape, volfrac)
u = fem.heat_distribution(x0, load)
umax = u.max()
def objective(x):
x = parametrization(x)
x = fem(x, load)
return x
def volume(x):
x = parametrization(x)
x = (x - cmin) / (cmax - cmin)
return np.mean(x)
plt.ion()
fig, ax = plt.subplots(1, 2)
im0 = ax[0].imshow(parametrization(x0).T, cmap="gray_r", vmin=cmin, vmax=cmax)
im1 = ax[1].imshow(parametrization(x0).T)
fig.tight_layout()
def volume_constraint(x, gd):
v, g = value_and_grad(volume)(x)
if gd.size > 0:
gd[:] = g
return v - volfrac
def nlopt_obj(x, gd):
c, dc = value_and_grad(objective)(x)
u = fem.heat_distribution(x, load)
u = u.reshape(fixed.shape)
if gd.size > 0:
gd[:] = dc.ravel()
im0.set_data(parametrization(x).T)
im1.set_data(u.T)
im1.set_clim([0, umax])
plt.pause(0.1)
return c
opt = nlopt.opt(nlopt.LD_MMA, x0.size)
opt.add_inequality_constraint(volume_constraint, 1e-6)
opt.set_min_objective(nlopt_obj)
opt.set_lower_bounds(0)
opt.set_upper_bounds(1)
opt.set_maxeval(max_its)
opt.optimize(x0.ravel())
plt.show(block=True)