NumOpt 0.0.3__tar.gz → 0.0.4__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.
@@ -1,4 +1,4 @@
1
1
  from NumOpt.opti import *
2
2
  from NumOpt.cprint import *
3
3
 
4
- __version__ = "0.0.3"
4
+ __version__ = "0.0.4"
@@ -0,0 +1,198 @@
1
+ from ..opti import asb, anp, cas, np
2
+ from scipy.special import comb
3
+ from ..cprint import cprint_green
4
+
5
+
6
+ class Bezier:
7
+ def __init__(self, control_points):
8
+ self.control_points = control_points
9
+ self.setup()
10
+
11
+ def setup(self):
12
+ self.order = self.control_points.shape[0] - 1
13
+ self.ndim = self.control_points.shape[1]
14
+ self._K = comb(self.order, np.arange(self.order + 1))
15
+ self._C = np.tile(self._K, (self.ndim, 1)).T * self.control_points
16
+
17
+ def __call__(self, t):
18
+ t = anp.reshape(t, (1, -1))
19
+ ti = []
20
+ t_ni = []
21
+ t_ = 1 - t
22
+ for i in range(self.order + 1):
23
+ ti.append(t**i)
24
+ t_ni.append(t_ ** (self.order - i))
25
+ ti = anp.concatenate(ti, axis=0)
26
+ t_ni = anp.concatenate(t_ni, axis=0)
27
+ t_mat = (ti * t_ni).T
28
+ pts = t_mat @ self._C
29
+ return pts
30
+
31
+
32
+ class BezierAirfoil:
33
+ def __init__(self, ctu, ctl):
34
+ self.ctu = ctu
35
+ self.ctl = ctl
36
+
37
+ self.bezier_upper = Bezier(self.ctu)
38
+ self.bezier_lower = Bezier(self.ctl)
39
+
40
+ self.__thickness = self.ctu[-1, 1] - self.ctl[-1, 1]
41
+ self.__symmetry = False
42
+
43
+ def upper_coordinates(self, t):
44
+ pts = self.bezier_upper(t)[::-1, :]
45
+ return pts
46
+
47
+ def lower_coordinates(self, t):
48
+ pts = self.bezier_lower(t)
49
+ return pts
50
+
51
+ def coordinates(self, t):
52
+ pts_u = self.upper_coordinates(t)
53
+ pts_l = self.lower_coordinates(t)
54
+
55
+ pts = anp.concatenate([pts_u[:-1, :], pts_l])
56
+ return pts
57
+
58
+ @property
59
+ def thickness(self):
60
+ return self.__thickness
61
+
62
+ @property
63
+ def symmetry(self):
64
+ return self.__symmetry
65
+
66
+ def set_thickness(self, thickness):
67
+ thickness = thickness
68
+ old_thickness = self.thickness
69
+ delta_thickness = thickness - old_thickness
70
+
71
+ t = anp.cosspace(0, 1, 100)
72
+
73
+ upper_coords = self.upper_coordinates(t)
74
+ upper_coords[:, 1] += upper_coords[:, 0] * delta_thickness / 2.0
75
+ lower_coords = self.lower_coordinates(t)
76
+ lower_coords[:, 1] -= lower_coords[:, 0] * delta_thickness / 2.0
77
+
78
+ new_af = self.fit(upper_coords, lower_coords, nctu=self.ctu.shape[0], nctl=self.ctl.shape[0], symmetry=self.symmetry)
79
+ return new_af
80
+
81
+ @staticmethod
82
+ def fit(upper_coordinates, lower_coordinates, nctu=7, nctl=7, symmetry=False):
83
+ default_options = {
84
+ "ipopt.sb": "yes",
85
+ "ipopt.max_iter": 1000,
86
+ "ipopt.max_cpu_time": 1e20,
87
+ "ipopt.mu_strategy": "adaptive",
88
+ "ipopt.fast_step_computation": "yes",
89
+ "detect_simple_bounds": False,
90
+ "expand": True,
91
+ # =======================
92
+ # if verbose
93
+ # "ipopt.print_level": 5,
94
+ # =======================
95
+ # =============================
96
+ # if no verbose
97
+ "print_time": False,
98
+ "ipopt.print_level": 0,
99
+ # =============================.
100
+ # ============================
101
+ # This is a heuristic that tends to result in more robust convergence on highly nonconvex problems.
102
+ # On convex problems and larger problems, the default setting ("adaptive") tends to result in faster convergence.
103
+ # ===========================
104
+ # "ipopt.mu_strategy": "monotone",
105
+ # ===============================
106
+ # This is another heuristic that tells the optimizer to focus on finding the feasible space initially.
107
+ # This can be good when you know your initial guess is very far from satisfying all constraints.
108
+ # "ipopt.start_with_resto": "yes",
109
+ # ===============================
110
+ }
111
+
112
+ # ------------------------ upper -------------------------------
113
+ opti = cas.Opti()
114
+ ctu = opti.variable(nctu, 2)
115
+ ctl = opti.parameter(nctl, 2)
116
+
117
+ af = BezierAirfoil(ctu=ctu, ctl=ctl)
118
+ # t = anp.cosspace(0, 1, upper_coordinates.shape[0])
119
+ t = opti.variable(upper_coordinates.shape[0])
120
+ coords = af.upper_coordinates(t)
121
+
122
+ # residual = cas.sum((coords[:, 1] - upper_coordinates[:, 1]) ** 2)
123
+ dist = coords - upper_coordinates
124
+ residual = cas.sum(cas.dot(dist, dist))
125
+
126
+ opti.subject_to(
127
+ [
128
+ # coords[:, 0] == upper_coordinates[:, 0],
129
+ ctu[0, 0] == 0.0,
130
+ ctu[0, 1] == 0.0,
131
+ ctu[1, 0] == 0.0,
132
+ ctu[-1, 0] == 1.0,
133
+ ctu[-1, 1] == upper_coordinates[0, 1],
134
+ opti.bounded(0.0, t, 1.0),
135
+ opti.bounded(0.0, ctu[:, 0], 1.0),
136
+ cas.diff(t) >= 0.0,
137
+ cas.diff(ctu[:, 0]) >= 0.0,
138
+ ]
139
+ )
140
+
141
+ opti.minimize(residual)
142
+ opti.solver("ipopt", default_options)
143
+ opti.set_initial(ctu[:, 0], np.linspace(0, 1, nctu))
144
+ opti.set_initial(ctu[:, 1], 0.05)
145
+ opti.set_initial(t, np.linspace(0, 1, upper_coordinates.shape[0]))
146
+
147
+ # cprint_green("fit upper...")
148
+ sol = opti.solve()
149
+
150
+ ctu_sol = sol.value(ctu)
151
+
152
+ # --------------------------- lower ------------------------------------------
153
+ if symmetry:
154
+ ctl_sol = np.array(ctu_sol)
155
+ ctl_sol[:, 1] = -ctl_sol[:, 1]
156
+ else:
157
+ opti = cas.Opti()
158
+ ctu = opti.parameter(nctu, 2)
159
+ ctl = opti.variable(nctl, 2)
160
+
161
+ af = BezierAirfoil(ctu=ctu, ctl=ctl)
162
+ # t = anp.cosspace(0, 1, upper_coordinates.shape[0])
163
+ t = opti.variable(lower_coordinates.shape[0])
164
+ coords = af.lower_coordinates(t)
165
+
166
+ dist = coords - lower_coordinates
167
+ # residual = cas.sum((coords[:, 1] - lower_coordinates[:, 1]) ** 2)
168
+ residual = cas.sum(cas.dot(dist, dist))
169
+
170
+ opti.subject_to(
171
+ [
172
+ # coords[:, 0] == lower_coordinates[:, 0],
173
+ ctl[0, 0] == 0.0,
174
+ ctl[0, 1] == 0.0,
175
+ ctl[1, 0] == 0.0,
176
+ ctl[-1, 0] == 1.0,
177
+ ctl[-1, 1] == lower_coordinates[-1, 1],
178
+ opti.bounded(0.0, t, 1.0),
179
+ opti.bounded(0.0, ctl[:, 0], 1.0),
180
+ cas.diff(t) >= 0.0,
181
+ cas.diff(ctl[:, 0]) >= 0.0,
182
+ ]
183
+ )
184
+
185
+ opti.minimize(residual)
186
+ opti.solver("ipopt", default_options)
187
+ opti.set_initial(ctl[:, 0], np.linspace(0, 1, nctl))
188
+ opti.set_initial(ctl[:, 1], -0.1)
189
+ opti.set_initial(t, np.linspace(0, 1, lower_coordinates.shape[0]))
190
+
191
+ # cprint_green("fit lower...")
192
+ sol = opti.solve()
193
+
194
+ ctl_sol = sol.value(ctl)
195
+
196
+ af = BezierAirfoil(ctu=ctu_sol, ctl=ctl_sol)
197
+ af.__symmetry = symmetry
198
+ return af
@@ -1,5 +1,6 @@
1
1
  import aerosandbox.numpy as anp
2
2
  import aerosandbox as asb
3
+ import numpy as np
3
4
  import casadi as cas
4
5
  from typing import Callable, Any, Dict
5
6
  from .cprint import cprint_yellow
File without changes
@@ -0,0 +1,39 @@
1
+ import numpy as np
2
+ from scipy.spatial import Delaunay as DelaunayND
3
+
4
+ from ..cprint import cprint_green,cprint_magenta
5
+
6
+ class Delaunay1D(object):
7
+ def __init__(self,points):
8
+ self.points=np.reshape(points,(-1,1))
9
+ self.dim=len(self.points)
10
+ @property
11
+ def vertex_neighbor_vertices(self):
12
+ sord_idx=np.argsort(self.points.flatten())
13
+ idxptr=[0]
14
+ idx=[]
15
+ sort_points=np.arange(self.dim)[sord_idx]
16
+ ranks=np.argsort(sord_idx)
17
+ for _,vi in enumerate(ranks):
18
+ len_idx=len(idx)
19
+ if vi==0:
20
+ right=vi+1
21
+ right=sort_points[right]
22
+ idxptr.append(len_idx+1)
23
+ idx.append(right)
24
+ elif vi==self.dim-1:
25
+ left=vi-1
26
+ left=sort_points[left]
27
+ idxptr.append(len_idx+1)
28
+ idx.append(left)
29
+ else:
30
+ left=vi-1
31
+ left=sort_points[left]
32
+ right=vi+1
33
+ right=sort_points[right]
34
+ idxptr.append(len_idx+2)
35
+ idx.extend([left,right])
36
+
37
+ idxptr=np.array(idxptr)
38
+ idx=np.array(idx)
39
+ return idxptr,idx
@@ -0,0 +1,31 @@
1
+ import numpy as np
2
+ from ..cprint import cprint_green, cprint_red
3
+
4
+ class NormalScaler:
5
+ def __init__(self):
6
+ self._mean = None
7
+ self._std = None
8
+
9
+ def fit(self, dataset):
10
+ if dataset.ndim != 2:
11
+ cprint_red("The dataset ndim must = 2.\n")
12
+ exit(-1)
13
+ self._mean = np.mean(dataset, axis=0)
14
+ self._std = np.std(dataset, axis=0, ddof=1)
15
+ return self
16
+
17
+ def transform(self, dataset, target_mean, target_std):
18
+ new_dataset = (dataset - self._mean) / self._std
19
+ new_dataset = new_dataset * target_std + target_mean
20
+ return new_dataset
21
+
22
+
23
+ if __name__ == "__main__":
24
+ x = np.random.normal(0.0, 0.1, (1000, 1))
25
+
26
+ scaler = NormalScaler().fit(x)
27
+ print(scaler._mean, scaler._std)
28
+
29
+ new_x = scaler.transform(dataset=x, target_mean=2.0, target_std=10)
30
+ new_scaler=NormalScaler().fit(new_x)
31
+ print(new_scaler._mean,new_scaler._std)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NumOpt
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: pti is a Python package that helps you design and optimize engineered systems.
5
5
  Home-page: https://github.com/Zcaic/NumOpt.git
6
6
  Author: Zcaic
@@ -12,5 +12,10 @@ NumOpt.egg-info/requires.txt
12
12
  NumOpt.egg-info/top_level.txt
13
13
  NumOpt/FSI/__init__.py
14
14
  NumOpt/FSI/tools.py
15
+ NumOpt/airfoil/bezier.py
15
16
  NumOpt/nx/__init__.py
16
- NumOpt/nx/tools.py
17
+ NumOpt/nx/tools.py
18
+ NumOpt/optimize/__init__.py
19
+ NumOpt/optimize/hxy_optimization.py
20
+ NumOpt/preprocess/scaler.py
21
+ test/test01.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NumOpt
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: pti is a Python package that helps you design and optimize engineered systems.
5
5
  Home-page: https://github.com/Zcaic/NumOpt.git
6
6
  Author: Zcaic
@@ -0,0 +1,146 @@
1
+ from NumOpt.airfoil.bezier import Bezier, BezierAirfoil
2
+ from NumOpt.opti import cas,Opti
3
+ import numpy as np
4
+ import aerosandbox as asb
5
+
6
+
7
+ def test1():
8
+ opti=Opti()
9
+ T=opti.variable(init_guess=2.8e3*9.8)
10
+
11
+ A=np.pi*3.5**2
12
+ vi=(T/(2*1.225*A))**0.5
13
+
14
+ Pin=743e3
15
+
16
+ eta=T*vi/Pin
17
+
18
+ opti.subject_to([
19
+ eta==0.80
20
+ ])
21
+
22
+ opti.solver()
23
+ sol=opti.solve()
24
+ print(sol(T))
25
+
26
+ def test2():
27
+ af=asb.Airfoil("naca0012")
28
+ af_new=BezierAirfoil.fit(upper_coordinates=af.upper_coordinates(),lower_coordinates=af.lower_coordinates(),symmetry=True)
29
+ af_new=af_new.set_thickness(5e-3)
30
+ print(af_new.thickness)
31
+ coords = af_new.coordinates(np.linspace(0, 1, 100))
32
+
33
+ import matplotlib.pyplot as plt
34
+
35
+ fig = plt.figure()
36
+ ax = fig.add_subplot()
37
+ ax.plot(coords[:, 0], coords[:, 1],label="fit")
38
+ ax.plot(af.coordinates[:,0],af.coordinates[:,1],label="ori")
39
+ ax.plot(af_new.ctu[:,0],af_new.ctu[:,1],"o--",label="ctu")
40
+ ax.plot(af_new.ctl[:,0],af_new.ctl[:,1],"o--",label="ctl")
41
+ ax.legend()
42
+ plt.show()
43
+
44
+
45
+
46
+ def test3():
47
+ nx = 5
48
+
49
+ # inputs
50
+ # x = cas.GenMX.sym("x", nx, 1)
51
+
52
+ # max_x = anp.max(x)
53
+
54
+ # max_x_index = cas.find(max_x == x)
55
+
56
+ # ret = anp.concatenate([max_x_index, max_x], axis=1)
57
+
58
+ # func = cas.Function("func", [x], [ret])
59
+
60
+ # print(func(anp.array([1, 3, 3, 3, 5])))
61
+
62
+
63
+ def test4():
64
+ opti = cas.Opti()
65
+
66
+ # 声明变量K并设置为整数类型
67
+ K = opti.variable()
68
+ opti.set_domain(K, "integer")
69
+
70
+ # 定义数组并转换为MX类型
71
+ A = [3, 2, 1, 2, 3]
72
+ A = cas.MX(A)
73
+
74
+ # 构建目标函数:最小化A[K]
75
+ opti.minimize(A[K])
76
+
77
+ # 添加约束:确保K在数组有效范围内
78
+ opti.subject_to(0 <= (K <= 4))
79
+
80
+ # 设置求解器并求解
81
+ opti.solver("bonmin")
82
+ sol = opti.solve()
83
+
84
+ # 输出结果
85
+ print(sol.value(K))
86
+
87
+
88
+ def test5():
89
+ import sympy as sp
90
+
91
+ p = sp.symbols("p", complex=True)
92
+ v = sp.symbols("v")
93
+ m = sp.symbols("m")
94
+ r = sp.symbols("r")
95
+ b = sp.symbols("b")
96
+ K_h = sp.symbols("K_h")
97
+ K_alpha = sp.symbols("K_alpha")
98
+ S_alpha = sp.symbols("S_alpha")
99
+ I_alpha = sp.symbols("I_alpha")
100
+ a = sp.symbols("a")
101
+ pi = np.pi
102
+
103
+ A = sp.Matrix(
104
+ [
105
+ [
106
+ m * p**2 + 2 * pi * r * v * b * p + K_h,
107
+ S_alpha * p**2 + (1 - 2 * a) * pi * r * v * b**2 * p + 2 * pi * r * v**2 * b,
108
+ ],
109
+ [
110
+ S_alpha * p**2 - (2 * a + 1) * pi * r * v * b**2 * p,
111
+ I_alpha * p**2 + (2 * a *a) * pi * r * v * b**3 * p + K_alpha - (2 * a + 1) * pi * r * v**2 * b**2,
112
+ ],
113
+ ]
114
+ )
115
+
116
+ detA=A.det()
117
+
118
+ p_expr=sp.solve(detA,p)
119
+
120
+ # p_expr=sp.lambdify([v,m,r,b,K_h,K_alpha,S_alpha,I_alpha,a],p_expr)
121
+ return p_expr
122
+
123
+
124
+
125
+ def test6():
126
+ ctu = np.array([[0.0, 0.0], [0.0, 26.8], [122.7, 52.9], [392.0, 110.2], [710.4, 41.6], [850.5, 12.9], [1000.0, 0.0]])
127
+ ctl = np.array([[0.0, 0.0], [0.0, -26.6], [160.1, -36.0], [421.5, -71.3], [716.2, -20.8], [850.8, 8.5], [1000.0, 0.0]])
128
+
129
+ af = BezierAirfoil(ctu=ctu, ctl=ctl)
130
+ coords = af.coordinates(np.linspace(0, 1, 100))
131
+
132
+ import matplotlib.pyplot as plt
133
+
134
+ fig = plt.figure()
135
+ ax = fig.add_subplot()
136
+ ax.plot(coords[:, 0], coords[:, 1])
137
+ plt.show()
138
+
139
+
140
+ if __name__ == "__main__":
141
+ # test1()
142
+ test2()
143
+ # test3()
144
+ # test4()
145
+ # test5()
146
+ # test6()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes