class Profile1: def __init__(self, cp_s, cp_p, p=3, pitch=0.0, height=0.0): self._p = p self._pitch = pitch self._height = height if height == 0.0 and pitch == 0.0: self._cp_s = cp_s self._cp_p = cp_p else: self._cp_s = self._redefCP(cp_s) self._cp_p = self._redefCP(cp_p) self._prof_s = Bspline(self._cp_s, p=p) self._prof_p = Bspline(self._cp_p, p=p) def _redefCP(self, cp): pitch, height = self._pitch, self._height cp_new = [] for i in xrange(len(cp)): cp_new.append(Point(cp[i].x, cp[i].y + pitch, cp[i].z + height)) return cp_new def getProfS(self, u): return self._prof_s(u) def getProfP(self, u): return self._prof_p(u) def plot(self): self._prof_s.plot() self._prof_p.plot()
def __init__(self, l=2.0, A=2.0, m=-0.2, ncp=6, type=1, p=3): self._l = l self._A = A self._m = m self._ncp = ncp self._type = type self._xp = self._spacing() self._Pig = self._init_cp() self._P = self._cp() Bspline.__init__(self, self._P, p)
def __init__(self, l = 2.0, A = 2.0, m = -0.2, ncp = 6, type = 1, p = 3): self._l = l self._A = A self._m = m self._ncp = ncp self._type = type self._xp = self._spacing() self._Pig = self._init_cp() self._P = self._cp() Bspline.__init__(self, self._P, p)
def __init__(self, needleDef): """ Constructor l-> lenght A-> inlet Area m-> inlet derivative ncp-> number of Control Point type -> stretching function """ self._needleDef = needleDef self._P = needleDef.getCPc() self._corner = Bspline(self._P, p=2)
def __init__(self, cp_s, cp_p, p = 3, pitch = 0.0, height = 0.0 ): self._p = p self._pitch = pitch self._height = height if height == 0.0 and pitch == 0.0: self._cp_s = cp_s self._cp_p = cp_p else: self._cp_s = self._redefCP(cp_s) self._cp_p = self._redefCP(cp_p) self._prof_s = Bspline(self._cp_s, p = p) self._prof_p = Bspline(self._cp_p, p = p)
def __init__(self, cp_s, cp_p, p=3, pitch=0.0, height=0.0): self._p = p self._pitch = pitch self._height = height if height == 0.0 and pitch == 0.0: self._cp_s = cp_s self._cp_p = cp_p else: self._cp_s = self._redefCP(cp_s) self._cp_p = self._redefCP(cp_p) self._prof_s = Bspline(self._cp_s, p=p) self._prof_p = Bspline(self._cp_p, p=p)
def __init__(self,upper_points,lower_points,center_iine_controls,thickness_controls,name='shell'): self.Po = upper_points self.Pi = lower_points self.Po_bar = upper_points.copy() self.Pi_bar = lower_points.copy() self.name = name self.Cc = center_iine_controls self.Ct = thickness_controls self.bsc_o = Bspline(self.Cc,upper_points) self.bsc_i = Bspline(self.Cc,lower_points) self.bst_o = Bspline(self.Ct,upper_points) self.bst_i = Bspline(self.Ct,lower_points) self.r_mag = np.average(upper_points[:,1]) #for revolution of 2-d profile self.n_theta = 20 self.Theta = np.linspace(0,2*np.pi,self.n_theta) self.ones = np.ones(self.n_theta) self.sin_theta = np.sin(self.Theta) self.cos_theta = np.cos(self.Theta) #calculate derivatives #in polar coordinates self.dPo_bar_xqdCc = self.bsc_o.B.flatten() self.dPo_bar_rqdCc = self.r_mag*self.bsc_o.B.flatten() self.dPi_bar_xqdCc = self.bsc_i.B.flatten() self.dPi_bar_rqdCc = self.r_mag*self.bsc_i.B.flatten() self.dPo_bar_rqdCt = self.r_mag*self.bst_o.B.flatten() self.dPi_bar_rqdCt = -1*self.r_mag*self.bst_i.B.flatten() #Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = np.outer(self.dPo_bar_xqdCc,self.ones) self.dYoqdCc = np.outer(self.dPo_bar_rqdCc,self.sin_theta) self.dZoqdCc = np.outer(self.dPo_bar_rqdCc,self.cos_theta) self.dXiqdCc = np.outer(self.dPi_bar_xqdCc,self.ones) self.dYiqdCc = np.outer(self.dPi_bar_rqdCc,self.sin_theta) self.dZiqdCc = np.outer(self.dPi_bar_rqdCc,self.cos_theta) self.dYoqdCt = np.outer(self.dPo_bar_rqdCt,self.sin_theta) self.dZoqdCt = np.outer(self.dPo_bar_rqdCt,self.cos_theta) self.dYiqdCt = np.outer(self.dPi_bar_rqdCt,self.sin_theta) self.dZiqdCt = np.outer(self.dPi_bar_rqdCt,self.cos_theta)
def to_1D(M, n=None, order=4, deriv=2): if n == None: n = array(M.shape).max() r = (kpt(M.shape[0])**2)[:,newaxis,newaxis] \ + (kpt(M.shape[1])**2)[newaxis,:,newaxis] \ + (kpt(M.shape[2])**2)[newaxis,newaxis,:] r = sqrt(r) x0 = 0.0 L = r.max() h = L / n n += order - 1 # Add external points. shift = order - 1 # and shift left f = spline_func((x0, h, n), Bspline(order), False, shift, (x0, x0 + L), "grid") m = pspline_match(f, deriv, 2, 1.0e-8) m.append(reshape(r, -1), reshape(M, -1)) m.alpha = 0.0 # turn off smoothing m.maximize(maxiter=1) #m.dimensionality() #m.sample(samples,skip,toss) f.c = m.theta return m
def __init__(self,geom_points,control_points,name="body"): self.P = geom_points self.P_bar = geom_points.copy() self.C = control_points self.bs = Bspline(control_points,geom_points) self.name = name self.r_mag = np.average(geom_points[:,1]) #for revolution of 2-d profile self.n_theta = 20 self.Theta = np.linspace(0,2*np.pi,self.n_theta) self.ones = np.ones(self.n_theta) self.sin_theta = np.sin(self.Theta) self.cos_theta = np.cos(self.Theta) #calculate derivatives #in polar coordinates self.dP_bar_xqdC = self.bs.B.flatten() self.dP_bar_rqdC = self.r_mag*self.bs.B.flatten() #Project Polar derivatives into revolved cartisian coordinates self.dXqdC = np.outer(self.dP_bar_xqdC,self.ones) self.dYqdC = np.outer(self.dP_bar_rqdC,self.sin_theta) self.dZqdC = np.outer(self.dP_bar_rqdC,self.cos_theta)
class Corner(object): """ we define the needle to be inserted into the divergent part of the nozzle """ def __init__(self, needleDef): """ Constructor l-> lenght A-> inlet Area m-> inlet derivative ncp-> number of Control Point type -> stretching function """ self._needleDef = needleDef self._P = needleDef.getCPc() self._corner = Bspline(self._P, p = 2) def __call__(self, u): return self._corner(u) def plot(self): return self._corner.plot()
class Corner(object): """ we define the needle to be inserted into the divergent part of the nozzle """ def __init__(self, needleDef): """ Constructor l-> lenght A-> inlet Area m-> inlet derivative ncp-> number of Control Point type -> stretching function """ self._needleDef = needleDef self._P = needleDef.getCPc() self._corner = Bspline(self._P, p=2) def __call__(self, u): return self._corner(u) def plot(self): return self._corner.plot()
class NozzleComp: def __init__(self, cdDef, p = 3): self._cdDef = cdDef self._P = cdDef.getCP() self._p = p self._convDiv = Bspline(self._P, p = p) def __call__(self, u): return self._convDiv(u) def plot(self): self._convDiv.plot() def getCP(self): return self._P
class Profile1: def __init__(self, cp_s, cp_p, p = 3, pitch = 0.0, height = 0.0 ): self._p = p self._pitch = pitch self._height = height if height == 0.0 and pitch == 0.0: self._cp_s = cp_s self._cp_p = cp_p else: self._cp_s = self._redefCP(cp_s) self._cp_p = self._redefCP(cp_p) self._prof_s = Bspline(self._cp_s, p = p) self._prof_p = Bspline(self._cp_p, p = p) def _redefCP(self, cp): pitch, height = self._pitch, self._height cp_new = [] for i in xrange(len(cp)): cp_new.append(Point(cp[i].x, cp[i].y + pitch, cp[i].z + height)) return cp_new def getProfS(self, u): return self._prof_s(u) def getProfP(self, u): return self._prof_p(u) def plot(self): self._prof_s.plot() self._prof_p.plot()
def _err(self): xy_p, s = self._xy_p, self._s x = np.ones(len(s)) y = np.ones(len(s)) err = np.ones(len(s)) for i in xrange(len(s)): x[i], y[i], nul1 = Bspline.__call__(self, s[i]) err[i] = abs(xy_p[0,i]- x[i]) + abs(xy_p[1,i]- y[i]) #it may be vectorized # err = abs(xy_p[0,:]) return err
class Camberline: def __init__(self, cambCP, p=2): self._cambCP = cambCP self._cambDef = cambCP.getCambDef() self._p = p self._camb = Bspline(cambCP(), p=p) self._derCamb = DerBspline(self._camb, kth=1) def getCamb(self, u): return self._camb(u) def getDerCamb(self, u): return self._derCamb(u) def getCambDef(self): return self._cambDef def plotCamb(self): self._camb.plot() def plotDerCamb(self): self._deramb.plot()
def __init__(self, needleDef): """ Constructor l-> lenght A-> inlet Area m-> inlet derivative ncp-> number of Control Point type -> stretching function """ self._needleDef = needleDef self._P = needleDef.getCPt() self._tip = Bspline(self._P, p = 2)
def star_model_predict(Xpred, coefs, descr): BS, TS = Bspline(), Bspline() basis = [] for e in descr: type_, nr_splines, constraints, lam_c, knot_types = e[0], e[1], e[2], e[3], e[4] print("Process ", type_) time.sleep(0.2) if type_.startswith("s"): dim = int(type_[2]) B = BS.basismatrix(X=Xpred[:,dim-1], nr_splines=nr_splines, l=3, knot_type=knot_types)["basis"] elif type_.startswith("t"): dim1, dim2 = int(type_[2]), int(type_[4]) B = TS.tensorproduct_basismatrix(X=Xpred[:,[dim1-1, dim2-1]], nr_splines=nr_splines, l=(3,3), knot_type=knot_types)["basis"] else: print("Only B-splines (s) and tensor-product B-splines (t) are supported!") basis.append(B) # create combined basis matrix B = np.concatenate(basis, axis=1) y = B@coefs return dict(basis=B, y=y, X=Xpred)
def _err(self): xy_p, s = self._xy_p, self._s x = np.ones(len(s)) y = np.ones(len(s)) err = np.ones(len(s)) for i in xrange(len(s)): x[i], y[i], nul1 = Bspline.__call__(self, s[i]) err[i] = abs(xy_p[0, i] - x[i]) + abs( xy_p[1, i] - y[i]) #it may be vectorized # err = abs(xy_p[0,:]) return err
def test_bspline_curve(self): # 1. Prepare the data p = 3 p_list = np.array([[0, 1], [2, 4], [4, 1], [5, 2], [7, 3], [10, 8], [12, 7], [14, 0]], dtype='d') u_list = np.array([0, 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 4], dtype='d') u = np.linspace(u_list[0], u_list[-1], 100) # 2. Compute reference values curve_ref = occ_utils.bspline(p_list, u_list) points_ref = occ_utils.curve_dn( curve_ref, u, 0) # zero order derivative = curve points derivatives_ref = occ_utils.curve_dn(curve_ref, u, 1) points_ref = points_ref[:, 0:2] derivatives_ref = derivatives_ref[:, 0:2] # 3. Compute test values curve = Bspline(p, p_list, u_list) points = curve.points(u) derivatives = curve.derivatives(u, 1) # 4. Do the comparative points_test = np.isclose(points_ref, points, atol=1e-10) derivatives_test = np.isclose(derivatives_ref, derivatives, atol=1e-10) self.assertTrue(np.all(points_test) and np.all(derivatives_test))
def throughput_fiberextract(Felist, args): nifu = len(Felist) nw = len(Felist[0][0].data[0, :]) xp = np.linspace(0, 1, num=nw) nbspline = 12 a = np.linspace(0, 1, nbspline) knots = np.hstack([0, 0, np.vstack([a, a]).T.ravel(), 1, 1]) b = Bspline(knots, 3) basis = np.array([b(xi) for xi in xp]) B = np.zeros((nifu, nw)) for i in xrange(nifu): spec = biweight_location(Felist[i][0].data, axis=(0, )) mask = np.where((~np.isnan(spec)) * (~np.isinf(spec)) * (spec != 0))[0] sol = np.linalg.lstsq(basis[mask, :], spec[mask])[0] B[i, :] = np.dot(basis, sol) # if args.plot: # pltfile = op.join(args.outfolder, 'spectrum_%i.pdf' %i) # fig = plt.figure(figsize=(8, 6)) # plt.plot(xp, spec) # plt.plot(xp, B[i,:],'r--') # plt.xticks([]) # plt.xlabel('Wavelength') # plt.ylabel('Arbitrary Units') # plt.xlim([0, 1]) # fig.savefig(pltfile, dpi=150) # plt.close() if args.plot: norm = plt.Normalize() colors = plt.cm.viridis(norm(np.arange(nifu) + 1)) pltfile = op.join(args.outfolder, 'IFU_average_spectra.pdf') fig = plt.figure(figsize=(8, 6)) avgB = biweight_location(B, axis=(0, )) for i in xrange(nifu): with np.errstate(divide='ignore'): plt.plot(xp, B[i, :] / avgB, color=colors[i, 0:3], alpha=0.9) plt.xticks([]) plt.xlabel('Wavelength') plt.ylabel('Normalized Units') plt.xlim([0, 1]) plt.ylim([0.5, 1.5]) fig.savefig(pltfile, dpi=150) plt.close() return B, avgB
def star_model(descr, X, y): """Fit a structured additive regression model using B-splines to the data in (X,y). Parameters: ----------- descr : tuple of tuples - Describes the model structure, e.g. descr = ( ("s(1)", 100, "inc", 6000, "e"), ("t(1,2)", (12,10), ("none", "none"), (6000,6000), ("e", "e")), ), describing a model using a P-spline with increasing constraint and 100 basis functions for dimension 1 and a tensor-product P-spline without constraints using 12 and 10 basis functions for the respective dimension. X : array - np.array of the input data, shape (n_samples, n_dim) y : array - np.array of the target data, shape (n_samples, ) Returns: -------- d : dict - Returns a dictionary with the following key-value pairs: basis=B, smoothness=S, constraint=K, opt_lambdas=optimal_lambdas, coef_=coef_pls, weights=weights """ BS, TS = Bspline(), Bspline() coefs = [] basis, smoothness = [], [] constr, optimal_lambdas = [], [] weights, weights_compare = [], [] S, K = [], [] for e in descr: type_, nr_splines, constraints, lam_c, knot_types = e[0], e[1], e[2], e[3], e[4] print("Process ", type_) if type_.startswith("s"): dim = int(type_[2]) B = BS.basismatrix(X=X[:,dim-1], nr_splines=nr_splines, l=3, knot_type=knot_types)["basis"] Ds = mm(nr_splines, constraint="smooth", dim=dim-1) Dc = mm(nr_splines, constraint=constraints, dim=dim-1) lam = BS.calc_GCV(X=X[:,dim-1], y=y, nr_splines=nr_splines, l=3, knot_type=knot_types, nr_lam=50)["best_lambda"] coef_pls = BS.fit_Pspline(X=X[:,dim-1], y=y, nr_splines=nr_splines, l=3, knot_type=knot_types, lam=lam)["coef_"] W = check_constraint(coef=coef_pls, constraint=constraints, y=y, B=B) weights.append(W) weights_compare += list(W) elif type_.startswith("t"): print("Constraint = ", constraints) dim1, dim2 = int(type_[2]), int(type_[4]) B = TS.tensorproduct_basismatrix(X=X[:,[dim1-1, dim2-1]], nr_splines=nr_splines, l=(3,3), knot_type=knot_types)["basis"] Ds1 = mm(nr_splines, constraint="smooth", dim=dim1-1) Ds2 = mm(nr_splines, constraint="smooth", dim=dim2-1) Dc1 = mm(nr_splines, constraint=constraints[0], dim=dim1-1) Dc2 = mm(nr_splines, constraint=constraints[1], dim=dim2-1) lam = TS.calc_GCV_2d(X=X[:,[dim1-1, dim2-1]], y=y, nr_splines=nr_splines, l=(3,3), knot_type=knot_types, nr_lam=50)["best_lambda"] coef_pls = TS.fit_Pspline(X=X[:,[dim1-1, dim2-1]], y=y, nr_splines=nr_splines, l=(3,3), knot_type=knot_types, lam=lam)["coef_"] W1 = check_constraint_dim1(coef_pls, nr_splines=nr_splines, constraint=constraints[0]) W2 = check_constraint_dim2(coef_pls, nr_splines=nr_splines, constraint=constraints[1]) weights.append((W1, W2)) weights_compare += list(W1) + list(W2) Ds = (Ds1, Ds2) Dc = (Dc1, Dc2) else: print("Only B-splines (s) and tensor-product B-splines (t) are supported!") basis.append(B) smoothness.append(Ds) constr.append(Dc) optimal_lambdas.append(lam) coefs.append(coef_pls) coef_pls = np.concatenate(coefs) # create combined basis matrix B = np.concatenate(basis, axis=1) # create combined smoothness matrix for i, s in enumerate(smoothness): if len(s) == 2: S.append(optimal_lambdas[i]*(s[0].T @ s[0] + s[1].T@s[1])) else: S.append(optimal_lambdas[i]*(s.T@s)) S = block_diag(*S) # create combined constraint matrix for i, c in enumerate(constr): if len(c) == 2: K.append(6000*(c[0].T @ np.diag(weights[i][0]) @ c[0]) + 6000*(c[1].T @np.diag(weights[i][1]) @ c[1])) else: K.append(6000* (c.T@ np.diag(weights[i])@c)) K = block_diag(*K) weights_old = [0]*len(weights_compare) iterIdx = 1 BtB = B.T @ B Bty = B.T @ y # Iterate till no change in weights df = pd.DataFrame(data=dict(w0=np.ones(2*12*10+100+100-2))) while not (weights_compare == weights_old): weights_old = weights_compare coef_pls = np.linalg.pinv(BtB + S + K) @ (Bty) weights, weights_compare = check_constraint_full(coef_=coef_pls, descr=descr, basis=B, y=y) # weights = check_constraint_full(coef_=coef_pls, descr=m, basis=B, y=y) print(f" Iteration {iterIdx} ".center(50, "=")) print(f"MSE = {mean_squared_error(y, B@coef_pls).round(7)}".center(50, "-")) K = [] print("Calculate new constraint matrix K".center(50,"-")) for i, c in enumerate(constr): if len(c) == 2: K.append(descr[i][3][0]*(c[0].T @ np.diag(weights[i][0]) @ c[0]) + descr[i][3][0]*(c[1].T @np.diag(weights[i][1]) @ c[1])) else: K.append(descr[i][3]*(c.T@ np.diag(weights[i])@c)) K = block_diag(*K) df = pd.concat([df, pd.DataFrame(data={"w"+str(iterIdx):weights_compare})], axis=1) if iterIdx > 200: print("breaking") break iterIdx += 1 print("Iteration Finished".center(50, "#")) return dict(basis=B, smoothness=S, constraint=K, opt_lambdas=optimal_lambdas, coef_=coef_pls, weights=weights)
def __init__(self, name, edges, L=None, excl=None): # internal vars SplineTerm.__init__(self, name, Bspline(6), 100, 0.0, 11.0, 2) self.edges = set(srt2(*e) for e in edges if e[0] != e[1]) self.excl = excl self.L = L
def __init__(self, name, angs): SplineTerm.__init__(self, name, Bspline(4), 90, -1.0, 2.0, 0) self.angs = angs
def plotLine(self): normalLine = self._normalLine for i in xrange(len(normalLine)): normalLine[i].plot() # class Camberline(object): # """ # classdocs # """ # # # def __init__(self, beta_in, beta_out, stugger): # # """ # Constructor # # """ if __name__ == '__main__': # prova = Angle(30.0) # print prova.getAngle() # print prova() # prova = CP_camberline() camb = Bspline(prova()) camb.plot() show()
class Body(object): """FFD class for solid bodies which only have one surface""" def __init__(self, stl, controls, name="body", r_ref=None, x_ref=None): """stl must be an STL object""" self.stl = stl geom_points = stl.points self.coords = Coordinates(geom_points, cartesian=True) self.P = self.coords.cylindrical self.P_cart = self.coords.cartesian self.P_bar = geom_points.copy() #just initialization if isinstance(controls, int): X = geom_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, controls) C_r = np.zeros((controls, )) control_points = np.array(zip(C_x, C_r)) self.C = control_points self.n_controls = controls else: self.C = controls self.n_controls = len(controls) self.C_bar = self.C.copy() self.delta_C = np.zeros(self.C.shape) self.bs = Bspline(self.C, geom_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10**np.floor(np.log10(np.average(geom_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and( abs(geom_points[:, 2]) < 2E-6, geom_points[:, 1] > 0) points = geom_points[indecies] self.r_mag = 10**np.floor(np.log10(np.average( points[:, 1]))) #grab the order of magnitude of the average #for revolution of 2-d profile #self.n_theta = 20 #sgrab the theta values from the points self.Theta = self.P[:, 2] #this is too complex. shouldn't need to tile, then flatten later. self.sin_theta = np.tile(np.sin(self.Theta), (self.n_controls, 1)).T.flatten() self.cos_theta = np.tile(np.cos(self.Theta), (self.n_controls, 1)).T.flatten() # self.sin_theta = np.tile(np.sin(self.Theta),self.n_controls) # self.cos_theta = np.tile(np.cos(self.Theta),self.n_controls) #calculate derivatives #in polar coordinates self.dP_bar_xqdC = np.array(self.x_mag * self.bs.B.flatten()) self.dP_bar_rqdC = np.array(self.r_mag * self.bs.B.flatten()) #Project Polar derivatives into revolved cartisian coordinates self.dXqdC = self.dP_bar_xqdC.reshape(-1, self.n_controls) self.dYqdC = (self.dP_bar_rqdC * self.sin_theta).reshape( -1, self.n_controls) self.dZqdC = (self.dP_bar_rqdC * self.cos_theta).reshape( -1, self.n_controls) def copy(self): return copy.deepcopy(self) def deform(self, delta_C): """returns new point locations for the given motion of the control points""" self.delta_C = delta_C self.delta_C[:, 0] = self.delta_C[:, 0] * self.x_mag self.C_bar = self.C + self.delta_C delta_P = self.bs.calc(self.C_bar) self.P_bar = self.P.copy() self.P_bar[:, 0] = delta_P[:, 0] self.P_bar[:, 1] = self.P[:, 1] + self.r_mag * delta_P[:, 1] #transform to cartesian coordinates self.coords = Coordinates(self.P_bar, cartesian=False) self.P_bar_cart = self.coords.cartesian self.Xo = self.P_bar_cart[:, 0] self.Yo = self.P_bar_cart[:, 1] self.Zo = self.P_bar_cart[:, 2] self.stl.update_points(self.P_bar_cart) return self.P_bar
def __init__(self, stl, controls, name="body", r_ref=None, x_ref=None): """stl must be an STL object""" self.stl = stl geom_points = stl.points self.coords = Coordinates(geom_points, cartesian=True) self.P = self.coords.cylindrical self.P_cart = self.coords.cartesian self.P_bar = geom_points.copy() #just initialization if isinstance(controls, int): X = geom_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, controls) C_r = np.zeros((controls, )) control_points = np.array(zip(C_x, C_r)) self.C = control_points self.n_controls = controls else: self.C = controls self.n_controls = len(controls) self.C_bar = self.C.copy() self.delta_C = np.zeros(self.C.shape) self.bs = Bspline(self.C, geom_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10**np.floor(np.log10(np.average(geom_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and( abs(geom_points[:, 2]) < 2E-6, geom_points[:, 1] > 0) points = geom_points[indecies] self.r_mag = 10**np.floor(np.log10(np.average( points[:, 1]))) #grab the order of magnitude of the average #for revolution of 2-d profile #self.n_theta = 20 #sgrab the theta values from the points self.Theta = self.P[:, 2] #this is too complex. shouldn't need to tile, then flatten later. self.sin_theta = np.tile(np.sin(self.Theta), (self.n_controls, 1)).T.flatten() self.cos_theta = np.tile(np.cos(self.Theta), (self.n_controls, 1)).T.flatten() # self.sin_theta = np.tile(np.sin(self.Theta),self.n_controls) # self.cos_theta = np.tile(np.cos(self.Theta),self.n_controls) #calculate derivatives #in polar coordinates self.dP_bar_xqdC = np.array(self.x_mag * self.bs.B.flatten()) self.dP_bar_rqdC = np.array(self.r_mag * self.bs.B.flatten()) #Project Polar derivatives into revolved cartisian coordinates self.dXqdC = self.dP_bar_xqdC.reshape(-1, self.n_controls) self.dYqdC = (self.dP_bar_rqdC * self.sin_theta).reshape( -1, self.n_controls) self.dZqdC = (self.dP_bar_rqdC * self.cos_theta).reshape( -1, self.n_controls)
def __init__( self, outer_stl, inner_stl, center_line_controls, thickness_controls, name="shell", r_ref=None, x_ref=None ): self.outer_stl = outer_stl self.inner_stl = inner_stl outer_points = outer_stl.points inner_points = inner_stl.points self.n_outer = len(outer_points) self.n_inner = len(inner_points) self.outer_coords = Coordinates(outer_points, cartesian=True) self.inner_coords = Coordinates(inner_points, cartesian=True) self.Po = self.outer_coords.cylindrical self.Pi = self.inner_coords.cylindrical self.Po_cart = self.outer_coords.cartesian self.Pi_cart = self.inner_coords.cartesian # just initialization for array size self.Po_bar = outer_points.copy() self.Pi_bar = inner_points.copy() self.name = name if isinstance(center_line_controls, int): X = outer_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, center_line_controls) C_r = np.zeros((center_line_controls,)) control_points = np.array(zip(C_x, C_r)) self.Cc = control_points self.n_c_controls = center_line_controls else: self.Cc = center_line_controls self.n_c_controls = len(center_line_controls) self.Cc_bar = self.Cc.copy() self.delta_Cc = np.zeros(self.Cc.shape) if isinstance(thickness_controls, int): X = inner_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, thickness_controls) C_r = np.zeros((thickness_controls,)) control_points = np.array(zip(C_x, C_r)) self.Ct = control_points self.n_t_controls = thickness_controls else: self.Ct = thickness_controls self.n_t_controls = len(thickness_controls) self.Ct_bar = self.Ct.copy() self.delta_Ct = np.zeros(self.Ct.shape) self.bsc_o = Bspline(self.Cc, outer_points) self.bsc_i = Bspline(self.Cc, inner_points) self.bst_o = Bspline(self.Ct, outer_points) self.bst_i = Bspline(self.Ct, inner_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10 ** np.floor(np.log10(np.average(outer_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and(abs(outer_points[:, 2]) < 2e-6, outer_points[:, 1] > 0) points = outer_points[indecies] self.r_mag = 10 ** np.floor( np.log10(np.average(points[:, 1])) ) # grab the order of magnitude of the average self.outer_theta = self.Po[:, 2] self.sin_outer_c_theta = np.tile(np.sin(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.cos_outer_c_theta = np.tile(np.cos(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.sin_outer_t_theta = np.tile(np.sin(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.cos_outer_t_theta = np.tile(np.cos(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.inner_theta = self.Pi[:, 2] self.sin_inner_c_theta = np.tile(np.sin(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.cos_inner_c_theta = np.tile(np.cos(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.sin_inner_t_theta = np.tile(np.sin(self.inner_theta), (self.n_t_controls, 1)).T.flatten() self.cos_inner_t_theta = np.tile(np.cos(self.inner_theta), (self.n_t_controls, 1)).T.flatten() # calculate derivatives # in polar coordinates self.dPo_bar_xqdCc = np.array(self.x_mag * self.bsc_o.B.flatten()) self.dPo_bar_rqdCc = np.array(self.r_mag * self.bsc_o.B.flatten()) self.dPi_bar_xqdCc = np.array(self.x_mag * self.bsc_i.B.flatten()) self.dPi_bar_rqdCc = np.array(self.r_mag * self.bsc_i.B.flatten()) self.dPo_bar_rqdCt = np.array(self.r_mag * self.bst_o.B.flatten()) self.dPi_bar_rqdCt = -1 * np.array(self.r_mag * self.bst_i.B.flatten()) # Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = self.dPo_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYoqdCc = (self.dPo_bar_rqdCc * self.sin_outer_c_theta).reshape(-1, self.n_c_controls) self.dZoqdCc = (self.dPo_bar_rqdCc * self.cos_outer_c_theta).reshape(-1, self.n_c_controls) self.dXiqdCc = self.dPi_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYiqdCc = (self.dPi_bar_rqdCc * self.sin_inner_c_theta).reshape(-1, self.n_c_controls) self.dZiqdCc = (self.dPi_bar_rqdCc * self.cos_inner_c_theta).reshape(-1, self.n_c_controls) self.dYoqdCt = (self.dPo_bar_rqdCt * self.sin_outer_t_theta).reshape(-1, self.n_t_controls) self.dZoqdCt = (self.dPo_bar_rqdCt * self.cos_outer_t_theta).reshape(-1, self.n_t_controls) self.dYiqdCt = (self.dPi_bar_rqdCt * self.sin_inner_t_theta).reshape(-1, self.n_t_controls) self.dZiqdCt = (self.dPi_bar_rqdCt * self.cos_inner_t_theta).reshape(-1, self.n_t_controls)
def __init__(self, cdDef, p = 3): self._cdDef = cdDef self._P = cdDef.getCP() self._p = p self._convDiv = Bspline(self._P, p = p)
class Shell(object): """FFD class for shell bodies which have two connected surfaces""" def __init__(self,upper_points,lower_points,center_iine_controls,thickness_controls,name='shell'): self.Po = upper_points self.Pi = lower_points self.Po_bar = upper_points.copy() self.Pi_bar = lower_points.copy() self.name = name self.Cc = center_iine_controls self.Ct = thickness_controls self.bsc_o = Bspline(self.Cc,upper_points) self.bsc_i = Bspline(self.Cc,lower_points) self.bst_o = Bspline(self.Ct,upper_points) self.bst_i = Bspline(self.Ct,lower_points) self.r_mag = np.average(upper_points[:,1]) #for revolution of 2-d profile self.n_theta = 20 self.Theta = np.linspace(0,2*np.pi,self.n_theta) self.ones = np.ones(self.n_theta) self.sin_theta = np.sin(self.Theta) self.cos_theta = np.cos(self.Theta) #calculate derivatives #in polar coordinates self.dPo_bar_xqdCc = self.bsc_o.B.flatten() self.dPo_bar_rqdCc = self.r_mag*self.bsc_o.B.flatten() self.dPi_bar_xqdCc = self.bsc_i.B.flatten() self.dPi_bar_rqdCc = self.r_mag*self.bsc_i.B.flatten() self.dPo_bar_rqdCt = self.r_mag*self.bst_o.B.flatten() self.dPi_bar_rqdCt = -1*self.r_mag*self.bst_i.B.flatten() #Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = np.outer(self.dPo_bar_xqdCc,self.ones) self.dYoqdCc = np.outer(self.dPo_bar_rqdCc,self.sin_theta) self.dZoqdCc = np.outer(self.dPo_bar_rqdCc,self.cos_theta) self.dXiqdCc = np.outer(self.dPi_bar_xqdCc,self.ones) self.dYiqdCc = np.outer(self.dPi_bar_rqdCc,self.sin_theta) self.dZiqdCc = np.outer(self.dPi_bar_rqdCc,self.cos_theta) self.dYoqdCt = np.outer(self.dPo_bar_rqdCt,self.sin_theta) self.dZoqdCt = np.outer(self.dPo_bar_rqdCt,self.cos_theta) self.dYiqdCt = np.outer(self.dPi_bar_rqdCt,self.sin_theta) self.dZiqdCt = np.outer(self.dPi_bar_rqdCt,self.cos_theta) def plot_geom(self,ax,initial_color='g',ffd_color='k'): if initial_color: ax.scatter(self.Po[:,0],self.Po[:,1],c=initial_color,s=50,label="%s initial geom"%self.name) ax.scatter(self.Pi[:,0],self.Pi[:,1],c=initial_color,s=50) ax.plot(self.Po[:,0],self.Po[:,1],c=initial_color) ax.plot(self.Pi[:,0],self.Pi[:,1],c=initial_color) if ffd_color: ax.scatter(self.Po_bar[:,0],self.Po_bar[:,1],c=ffd_color,s=50,label="%s ffd geom"%self.name) ax.scatter(self.Pi_bar[:,0],self.Pi_bar[:,1],c=ffd_color,s=50) ax.plot(self.Po_bar[:,0],self.Po_bar[:,1],c=ffd_color) ax.plot(self.Pi_bar[:,0],self.Pi_bar[:,1],c=ffd_color) def plot_centerline_spline(self,ax,point_color='r',line_color='b'): ax.scatter(self.Cc_bar[:,0],self.Cc_bar[:,1],c=point_color,s=50,label="%s Centerline Control Points"%self.name) map_points = self.bsc_o(np.linspace(0,1,100)) ax.plot(map_points[:,0],map_points[:,1],label="Centerline b-spline Curve",c=line_color) def plot_thickness_spline(self,ax,point_color='r',line_color='b'): ax.scatter(self.Ct_bar[:,0],self.Ct_bar[:,1],c=point_color,s=50,label="%s Thickness Control Points"%self.name) map_points = self.bsc_o(np.linspace(0,1,100)) ax.plot(map_points[:,0],map_points[:,1],label="Thickness b-spline Curve",c=line_color) def deform(self,delta_Cc,delta_Ct): """returns new point locations for the given motion of the control points for center-line and thickness""" self.Cc_bar = self.Cc+delta_Cc delta_Pc_o = self.bsc_o.calc(self.Cc_bar) delta_Pc_i = self.bsc_i.calc(self.Cc_bar) self.Ct_bar = self.Ct+delta_Ct delta_Pt_o = self.bst_o.calc(self.Ct_bar) delta_Pt_i = self.bst_i.calc(self.Ct_bar) self.Po_bar = self.Po.copy() self.Pi_bar = self.Pi.copy() self.Po_bar[:,0] = delta_Pc_o[:,0] self.Po_bar[:,1] = self.Po[:,1]+self.r_mag*(delta_Pc_o[:,1]+delta_Pt_o[:,1]) self.Pi_bar[:,0] = delta_Pc_i[:,0] self.Pi_bar[:,1] = self.Pi[:,1]+self.r_mag*(delta_Pc_i[:,1]-delta_Pt_i[:,1]) #Perform axial roation of 2-d polar coordiantes #outer surface Po_bar_r = self.Po_bar[:,1] self.Xo = np.outer(self.Po_bar[:,0],self.ones) self.Yo = np.outer(Po_bar_r,self.sin_theta) self.Zo = np.outer(Po_bar_r,self.cos_theta) #inner surface Pi_bar_r = self.Pi_bar[:,1] self.Xi = np.outer(self.Pi_bar[:,0],self.ones) self.Yi = np.outer(Pi_bar_r,self.sin_theta) self.Zi = np.outer(Pi_bar_r,self.cos_theta) return self.Po_bar,self.Pi_bar
def __init__(self, name, tors): SplineTerm.__init__(self, name, Bspline(4), 180, None, 2 * pi, 0) self.tors = tors
def __init__(self, dDistCP, p=2): self._dDistCP = dDistCP self._p = p self._dDist = Bspline(dDistCP, p)
def Temp(self): # load in all the defined properties num_of_points = 15 #Number of points used in the spline order = 5 #order of the spline plt_points = self.xgrid length = self.length start_time = self.start_time final_time = self.final_time time_step = self.time_step Left_BC_Type = self.Left_BC_Type Right_BC_Type = self.Right_BC_Type Left_BC = self.Left_BC Right_BC = self.Right_BC conductivity = self.conductivity rfct = self.heatCapacity source = self.source init = self.init rho = self.rho # Simulation Setup ==================================================== # Capacity Function --------------------------------------------------- #dk/(dphi) is needed later in the core in every loop # evaluating the derivative of conductivity with respect to phi # --------------------------------------------------------------------- def diff_conductivity(phi): eps = 1e-9 dc = (conductivity(phi + eps) - conductivity(phi)) / eps return (dc) # Capacity Function --------------------------------------------------- # evaluating coefficients of the passed on function via a system of linear eq. # --------------------------------------------------------------------- def capacity(r): A = np.array([[1, 1, 1, 1], [1, 2, 4, 8], [1, 3, 9, 27], [1, 4, 16, 64]]) B = np.array([r(1), r(2), r(3), r(4)]) rcoeff = np.linalg.solve(A, B) return (rcoeff) # Define Time and Space grid ------------------------------------------ x = np.linspace(0, length, num_of_points) # Space Grid t = np.arange(start_time, final_time, time_step) # Time Grid # Define Splines and Differentiation Matrices ------------------------- knot_vector = aptknt(x, order) # Creates knot points with Ghost points basis = Bspline(knot_vector, order) # Generate a vector of Spline Objects A0 = basis.collmat( x, deriv_order=0) # Generate Matrix A0 0st order derivative in space AA0 = basis.collmat( x, deriv_order=0) # Generate a Boundary condition free A0 version AA0[-1, -1] = 1 A1 = basis.collmat( x, deriv_order=1) # Generate Matrix A1 1st order derivative in space A2 = basis.collmat( x, deriv_order=2) # Generate Matrix A2 2st order derivative in space # Prepare "Smooth Plot Matrix" xx = np.linspace(0, length, plt_points) # Gird to Plot C = basis.collmat(xx) # Smooth Plot Matrix (read LaTeX notes) # Correct last spline A0[-1, -1] = 1 C[-1, -1] = 1 A1[-1] = -np.flip(A1[0], 0) # put first values of A1 to the last row # Prepare the inverse P to save time during the simulation ------------ if Left_BC_Type == 1: A0[0] = A1[0] #set 1st and last row to 0 if Right_BC_Type == 1: A0[-1] = A1[-1] #needed to implement BC P = spl.inv(A0) # Modify Formulation to implement Boundary Condition ------------------ A0[0] = 0 A1[0] = 0 A2[0] = 0 #First row is reserved for Boundary Condition A0[-1] = 0 A1[-1] = 0 A2[-1] = 0 # Last row is reserved for Boundary Condition # Time Evolution Matrix ----------------------------------------------- M = np.dot(P, A0) + (time_step * np.dot(P, A2) ) #only needed for the simple case #see core #initial c = coefficients for splines if isinstance(init, (int, float)) or len( init(x)) < len(x): #make the initial condition a function dummy = init #in case input is a number init = lambda x: dummy + 0 * x c = np.dot(spl.inv(AA0), init(x)) # Prepare Boundary Condition according to which function is given to the class BC = np.zeros((len(x), len(t))) BC[0] = Left_BC(t) BC[-1] = Right_BC(t) #Prepare a matrix with the source data (space, time) to not always call #the function in the loop, see core if isinstance(source, (int, float)): # make the source a function dummy1 = source #in case the input is a number, i.e.a constant source = lambda x, t: dummy1 + 0 * x + 0 * t xmg, tmg = np.meshgrid(x, t) sourceM = source(xmg, tmg) sourceM[:, 0] = 0 sourceM[:, -1] = 0 #set last and first row 0 for BC #Prepare Array to store results phi = np.zeros((len(t), len(xx))) # End of Simulation Setup ============================================= # MAIN LOOP ----------------------------------------------------------- # ===================================================================== # Decide which case is relevant and solve the according for loops in core.py file # Depending on which _BC_Type (either Neumann or Dirichlet) is radsed, #respective boundary conditions are taken into consideration. # ===================================================================== if Left_BC_Type == 0 and Right_BC_Type == 0: #Dirichlet on both sides print('Dirichlet condition on both sides') if isinstance(conductivity, (int, float)) == True and isinstance( rfct, (int, float)) == True: #k(phi) = k0 & r(phi) = r0 Conditions check if conductivity & capacity are constants print( 'Constant Conductivity and Capacity and Dirichlet boundary conditions' ) print('No source and no density is taken under consideration') k0 = conductivity r0 = rfct phi = core.simple_DD(M, t, c, k0, P, BC, C, phi) if isinstance(conductivity, (int, float)) == False and isinstance( rfct, (int, float)) == True: #Conductivity: k(phi) = k0 + k1*phi and Capacity: r(phi) = r0 print(r'Generic $k(\phi)$ and Capacity:$r(\phi) = r0$') r0 = rfct phi = core.genK_phi_DD(t, c, A0, A1, A2, diff_conductivity, conductivity, sourceM, r0, time_step, P, C, BC, phi, rho, x) if isinstance(conductivity, (int, float)) == False and isinstance( rfct, (int, float)) == False: #Conductivity: k(phi) & Capacity: r(phi) are both generic print( r'Generic Conductivity: $k(\phi)$ and Capacity: $r(\phi)$') r0 = capacity(rfct)[0] r1 = capacity(rfct)[1] r2 = capacity(rfct)[2] r3 = capacity(rfct)[3] phi = core.genK_genR_DD(t, c, A0, AA0, A1, A2, diff_conductivity, conductivity, sourceM, r0, r1, r2, r3, time_step, P, C, BC, phi, rho, x) if Left_BC_Type == 1 and Right_BC_Type == 0: # Neumann condition on RHS: print('Left side: Neumann- ; Right side: Dirichlet BC') print(r'Generic Conductivity: $k(\phi)$ and Capacity: $r(\phi)$') side = 0 r0 = capacity(rfct)[0] r1 = capacity(rfct)[1] r2 = capacity(rfct)[2] r3 = capacity(rfct)[3] phi = core.genK_genR_ND(t, c, A0, AA0, A1, A2, diff_conductivity, conductivity, sourceM, r0, r1, r2, r3, time_step, P, C, BC, phi, side, rho, x) if Left_BC_Type == 0 and Right_BC_Type == 1: # Neumann condition on RHS: print( 'Left side: Dirichlet- ; Right side: Neumann Boundary condition' ) print(r'Generic Conductivity: $k(\phi)$ and Capacity: $r(\phi)$') side = -1 r0 = capacity(rfct)[0] r1 = capacity(rfct)[1] r2 = capacity(rfct)[2] r3 = capacity(rfct)[3] phi = core.genK_genR_DN(t, c, A0, AA0, A1, A2, diff_conductivity, conductivity, sourceM, r0, r1, r2, r3, time_step, P, C, BC, phi, side, rho, x) if Left_BC_Type == 1 and Right_BC_Type == 1: # Neumann condition on RHS & LHS: print('Both sides Neumann Boundary condition') print(r'Generic Conductivity: $k(\phi)$ and Capacity: $r(\phi)$') r0 = capacity(rfct)[0] r1 = capacity(rfct)[1] r2 = capacity(rfct)[2] r3 = capacity(rfct)[3] phi = core.genK_genR_NN(t, c, A0, AA0, A1, A2, diff_conductivity, conductivity, sourceM, r0, r1, r2, r3, time_step, P, C, BC, phi, rho, x) return (phi) # in every case phi gets returned by the core
def __init__(self, name, edges): # internal vars SplineTerm.__init__(self, name, Bspline(4), 40, 0.0, 4.0, 2) self.edges = edges
SELECTED_DOTS = (186, 104, 131) size = [600, 600] screen = pygame.display.set_mode(size) pygame.display.set_caption("Example code for the draw module") done = False redraw_bspline = True redraw_nurbs = True spline = False weight = 1 got_c1 = False clock = pygame.time.Clock() bspline = Bspline(screen) nurbs = Nurbs(screen) redraw_all(iterative=True) ctrl_x = nurbs.x() ctrl_y = nurbs.y() weights = nurbs.w() while not done: clock.tick(20) for event in pygame.event.get(): if event.type == pygame.QUIT: done=True keys = pygame.key.get_pressed()
def __call__(self, A): P = self.get_P(A) self._fit = Bspline(P, self._p) return np.linalg.norm(self._err(), ord=2.0)
class Body(object): """FFD class for solid bodyies which only have one surface""" def __init__(self,geom_points,control_points,name="body"): self.P = geom_points self.P_bar = geom_points.copy() self.C = control_points self.bs = Bspline(control_points,geom_points) self.name = name self.r_mag = np.average(geom_points[:,1]) #for revolution of 2-d profile self.n_theta = 20 self.Theta = np.linspace(0,2*np.pi,self.n_theta) self.ones = np.ones(self.n_theta) self.sin_theta = np.sin(self.Theta) self.cos_theta = np.cos(self.Theta) #calculate derivatives #in polar coordinates self.dP_bar_xqdC = self.bs.B.flatten() self.dP_bar_rqdC = self.r_mag*self.bs.B.flatten() #Project Polar derivatives into revolved cartisian coordinates self.dXqdC = np.outer(self.dP_bar_xqdC,self.ones) self.dYqdC = np.outer(self.dP_bar_rqdC,self.sin_theta) self.dZqdC = np.outer(self.dP_bar_rqdC,self.cos_theta) def deform(self,delta_C): """returns new point locations for the given motion of the control points""" self.C_bar = self.C+delta_C delta_P = self.bs.calc(self.C_bar) self.P_bar = self.P.copy() self.P_bar[:,0] = delta_P[:,0] self.P_bar[:,1] = self.P[:,1]+self.r_mag*delta_P[:,1] #Perform axial roation of 2-d polar coordiantes P_bar_r = self.P_bar[:,1] self.Xo = np.outer(self.P_bar[:,0],self.ones) self.Yo = np.outer(P_bar_r,self.sin_theta) self.Zo = np.outer(P_bar_r,self.cos_theta) return self.P_bar def plot_spline(self,ax,point_color='r',line_color='b'): map_points = self.bs(np.linspace(0,1,100)) ax.plot(map_points[:,0],map_points[:,1],c=line_color,label="%s b-spline"%self.name) ax.scatter(self.C_bar[:,0],self.C_bar[:,1],c=point_color,label="%s control points"%self.name,s=50) def plot_geom(self,ax,initial_color='g',ffd_color='k'): if initial_color: ax.scatter(self.P[:,0],self.P[:,1],c=initial_color,s=50,label="%s initial geom"%self.name) ax.plot(self.P[:,0],self.P[:,1],c=initial_color) if ffd_color: ax.scatter(self.P_bar[:,0],self.P_bar[:,1],c=ffd_color,s=50,label="%s ffd geom"%self.name) ax.plot(self.P_bar[:,0],self.P_bar[:,1],c=ffd_color)
def __init__(self, stl, controls, name="body", r_ref=None, x_ref=None): """stl must be an STL object""" self.stl = stl geom_points = stl.points self.coords = Coordinates(geom_points, cartesian=True) self.P = self.coords.cylindrical self.P_cart = self.coords.cartesian self.P_bar = geom_points.copy() # just initialization if isinstance(controls, int): X = geom_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, controls) C_r = np.zeros((controls,)) control_points = np.array(zip(C_x, C_r)) self.C = control_points self.n_controls = controls else: self.C = controls self.n_controls = len(controls) self.C_bar = self.C.copy() self.delta_C = np.zeros(self.C.shape) self.bs = Bspline(self.C, geom_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10 ** np.floor(np.log10(np.average(geom_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and(abs(geom_points[:, 2]) < 2e-6, geom_points[:, 1] > 0) points = geom_points[indecies] self.r_mag = 10 ** np.floor( np.log10(np.average(points[:, 1])) ) # grab the order of magnitude of the average # for revolution of 2-d profile # self.n_theta = 20 # sgrab the theta values from the points self.Theta = self.P[:, 2] # this is too complex. shouldn't need to tile, then flatten later. self.sin_theta = np.tile(np.sin(self.Theta), (self.n_controls, 1)).T.flatten() self.cos_theta = np.tile(np.cos(self.Theta), (self.n_controls, 1)).T.flatten() # self.sin_theta = np.tile(np.sin(self.Theta),self.n_controls) # self.cos_theta = np.tile(np.cos(self.Theta),self.n_controls) # calculate derivatives # in polar coordinates self.dP_bar_xqdC = np.array(self.x_mag * self.bs.B.flatten()) self.dP_bar_rqdC = np.array(self.r_mag * self.bs.B.flatten()) # Project Polar derivatives into revolved cartisian coordinates self.dXqdC = self.dP_bar_xqdC.reshape(-1, self.n_controls) self.dYqdC = (self.dP_bar_rqdC * self.sin_theta).reshape(-1, self.n_controls) self.dZqdC = (self.dP_bar_rqdC * self.cos_theta).reshape(-1, self.n_controls)
class Shell(object): """FFD class for shell bodies which have two connected surfaces""" def __init__( self, outer_stl, inner_stl, center_line_controls, thickness_controls, name="shell", r_ref=None, x_ref=None ): self.outer_stl = outer_stl self.inner_stl = inner_stl outer_points = outer_stl.points inner_points = inner_stl.points self.n_outer = len(outer_points) self.n_inner = len(inner_points) self.outer_coords = Coordinates(outer_points, cartesian=True) self.inner_coords = Coordinates(inner_points, cartesian=True) self.Po = self.outer_coords.cylindrical self.Pi = self.inner_coords.cylindrical self.Po_cart = self.outer_coords.cartesian self.Pi_cart = self.inner_coords.cartesian # just initialization for array size self.Po_bar = outer_points.copy() self.Pi_bar = inner_points.copy() self.name = name if isinstance(center_line_controls, int): X = outer_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, center_line_controls) C_r = np.zeros((center_line_controls,)) control_points = np.array(zip(C_x, C_r)) self.Cc = control_points self.n_c_controls = center_line_controls else: self.Cc = center_line_controls self.n_c_controls = len(center_line_controls) self.Cc_bar = self.Cc.copy() self.delta_Cc = np.zeros(self.Cc.shape) if isinstance(thickness_controls, int): X = inner_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, thickness_controls) C_r = np.zeros((thickness_controls,)) control_points = np.array(zip(C_x, C_r)) self.Ct = control_points self.n_t_controls = thickness_controls else: self.Ct = thickness_controls self.n_t_controls = len(thickness_controls) self.Ct_bar = self.Ct.copy() self.delta_Ct = np.zeros(self.Ct.shape) self.bsc_o = Bspline(self.Cc, outer_points) self.bsc_i = Bspline(self.Cc, inner_points) self.bst_o = Bspline(self.Ct, outer_points) self.bst_i = Bspline(self.Ct, inner_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10 ** np.floor(np.log10(np.average(outer_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and(abs(outer_points[:, 2]) < 2e-6, outer_points[:, 1] > 0) points = outer_points[indecies] self.r_mag = 10 ** np.floor( np.log10(np.average(points[:, 1])) ) # grab the order of magnitude of the average self.outer_theta = self.Po[:, 2] self.sin_outer_c_theta = np.tile(np.sin(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.cos_outer_c_theta = np.tile(np.cos(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.sin_outer_t_theta = np.tile(np.sin(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.cos_outer_t_theta = np.tile(np.cos(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.inner_theta = self.Pi[:, 2] self.sin_inner_c_theta = np.tile(np.sin(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.cos_inner_c_theta = np.tile(np.cos(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.sin_inner_t_theta = np.tile(np.sin(self.inner_theta), (self.n_t_controls, 1)).T.flatten() self.cos_inner_t_theta = np.tile(np.cos(self.inner_theta), (self.n_t_controls, 1)).T.flatten() # calculate derivatives # in polar coordinates self.dPo_bar_xqdCc = np.array(self.x_mag * self.bsc_o.B.flatten()) self.dPo_bar_rqdCc = np.array(self.r_mag * self.bsc_o.B.flatten()) self.dPi_bar_xqdCc = np.array(self.x_mag * self.bsc_i.B.flatten()) self.dPi_bar_rqdCc = np.array(self.r_mag * self.bsc_i.B.flatten()) self.dPo_bar_rqdCt = np.array(self.r_mag * self.bst_o.B.flatten()) self.dPi_bar_rqdCt = -1 * np.array(self.r_mag * self.bst_i.B.flatten()) # Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = self.dPo_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYoqdCc = (self.dPo_bar_rqdCc * self.sin_outer_c_theta).reshape(-1, self.n_c_controls) self.dZoqdCc = (self.dPo_bar_rqdCc * self.cos_outer_c_theta).reshape(-1, self.n_c_controls) self.dXiqdCc = self.dPi_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYiqdCc = (self.dPi_bar_rqdCc * self.sin_inner_c_theta).reshape(-1, self.n_c_controls) self.dZiqdCc = (self.dPi_bar_rqdCc * self.cos_inner_c_theta).reshape(-1, self.n_c_controls) self.dYoqdCt = (self.dPo_bar_rqdCt * self.sin_outer_t_theta).reshape(-1, self.n_t_controls) self.dZoqdCt = (self.dPo_bar_rqdCt * self.cos_outer_t_theta).reshape(-1, self.n_t_controls) self.dYiqdCt = (self.dPi_bar_rqdCt * self.sin_inner_t_theta).reshape(-1, self.n_t_controls) self.dZiqdCt = (self.dPi_bar_rqdCt * self.cos_inner_t_theta).reshape(-1, self.n_t_controls) def copy(self): return copy.deepcopy(self) def plot_geom(self, ax, initial_color="g", ffd_color="k"): if initial_color: ax.scatter(self.Po[:, 0], self.Po[:, 1], c=initial_color, s=50, label="%s initial geom" % self.name) ax.scatter(self.Pi[:, 0], self.Pi[:, 1], c=initial_color, s=50) ax.plot(self.Po[:, 0], self.Po[:, 1], c=initial_color) ax.plot(self.Pi[:, 0], self.Pi[:, 1], c=initial_color) if ffd_color: ax.scatter(self.Po_bar[:, 0], self.Po_bar[:, 1], c=ffd_color, s=50, label="%s ffd geom" % self.name) ax.scatter(self.Pi_bar[:, 0], self.Pi_bar[:, 1], c=ffd_color, s=50) ax.plot(self.Po_bar[:, 0], self.Po_bar[:, 1], c=ffd_color) ax.plot(self.Pi_bar[:, 0], self.Pi_bar[:, 1], c=ffd_color) def plot_centerline_spline(self, ax, point_color="r", line_color="b"): ax.scatter( self.Cc_bar[:, 0], self.Cc_bar[:, 1], c=point_color, s=50, label="%s Centerline Control Points" % self.name ) map_points = self.bsc_o(np.linspace(0, 1, 100)) ax.plot(map_points[:, 0], map_points[:, 1], label="Centerline b-spline Curve", c=line_color) def plot_thickness_spline(self, ax, point_color="r", line_color="b"): ax.scatter( self.Ct_bar[:, 0], self.Ct_bar[:, 1], c=point_color, s=50, label="%s Thickness Control Points" % self.name ) map_points = self.bst_o(np.linspace(0, 1, 100)) ax.plot(map_points[:, 0], map_points[:, 1], label="Thickness b-spline Curve", c=line_color) def deform(self, delta_Cc, delta_Ct): """returns new point locations for the given motion of the control points for center-line and thickness""" self.delta_Cc = delta_Cc self.delta_Cc[:, 0] *= self.x_mag self.Cc_bar = self.Cc + self.delta_Cc delta_Pc_o = self.bsc_o.calc(self.Cc_bar) delta_Pc_i = self.bsc_i.calc(self.Cc_bar) self.delta_Ct = delta_Ct self.Ct_bar = self.Ct + self.delta_Ct delta_Pt_o = self.bst_o.calc(self.Ct_bar) delta_Pt_i = self.bst_i.calc(self.Ct_bar) self.Po_bar = self.Po.copy() self.Pi_bar = self.Pi.copy() self.Po_bar[:, 0] = delta_Pc_o[:, 0] self.Po_bar[:, 1] = self.Po[:, 1] + self.r_mag * (delta_Pc_o[:, 1] + delta_Pt_o[:, 1]) self.Pi_bar[:, 0] = delta_Pc_i[:, 0] self.Pi_bar[:, 1] = self.Pi[:, 1] + self.r_mag * (delta_Pc_i[:, 1] - delta_Pt_i[:, 1]) # transform to cartesian coordinates self.outer_coords = Coordinates(self.Po_bar, cartesian=False) self.inner_coords = Coordinates(self.Pi_bar, cartesian=False) # Perform axial roation of 2-d polar coordiantes # outer surface self.Po_bar_cart = self.outer_coords.cartesian self.Xo = self.Po_bar_cart[:, 0] self.Yo = self.Po_bar_cart[:, 1] self.Zo = self.Po_bar_cart[:, 2] self.outer_stl.update_points(self.Po_bar_cart) # inner surface self.Pi_bar_cart = self.inner_coords.cartesian self.Xi = self.Po_bar_cart[:, 0] self.Yi = self.Po_bar_cart[:, 1] self.Zi = self.Po_bar_cart[:, 2] self.inner_stl.update_points(self.Pi_bar_cart) return self.Po_bar, self.Pi_bar
class Shell(object): """FFD class for shell bodies which have two connected surfaces""" def __init__(self, outer_stl, inner_stl, center_line_controls, thickness_controls, name='shell', r_ref=None, x_ref=None): self.outer_stl = outer_stl self.inner_stl = inner_stl outer_points = outer_stl.points inner_points = inner_stl.points self.n_outer = len(outer_points) self.n_inner = len(inner_points) self.outer_coords = Coordinates(outer_points, cartesian=True) self.inner_coords = Coordinates(inner_points, cartesian=True) self.Po = self.outer_coords.cylindrical self.Pi = self.inner_coords.cylindrical self.Po_cart = self.outer_coords.cartesian self.Pi_cart = self.inner_coords.cartesian #just initialization for array size self.Po_bar = outer_points.copy() self.Pi_bar = inner_points.copy() self.name = name if isinstance(center_line_controls, int): X = outer_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, center_line_controls) C_r = np.zeros((center_line_controls, )) control_points = np.array(zip(C_x, C_r)) self.Cc = control_points self.n_c_controls = center_line_controls else: self.Cc = center_line_controls self.n_c_controls = len(center_line_controls) self.Cc_bar = self.Cc.copy() self.delta_Cc = np.zeros(self.Cc.shape) if isinstance(thickness_controls, int): X = inner_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, thickness_controls) C_r = np.zeros((thickness_controls, )) control_points = np.array(zip(C_x, C_r)) self.Ct = control_points self.n_t_controls = thickness_controls else: self.Ct = thickness_controls self.n_t_controls = len(thickness_controls) self.Ct_bar = self.Ct.copy() self.delta_Ct = np.zeros(self.Ct.shape) self.bsc_o = Bspline(self.Cc, outer_points) self.bsc_i = Bspline(self.Cc, inner_points) self.bst_o = Bspline(self.Ct, outer_points) self.bst_i = Bspline(self.Ct, inner_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10**np.floor(np.log10(np.average(outer_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and( abs(outer_points[:, 2]) < 2E-6, outer_points[:, 1] > 0) points = outer_points[indecies] self.r_mag = 10**np.floor(np.log10(np.average( points[:, 1]))) #grab the order of magnitude of the average self.outer_theta = self.Po[:, 2] self.sin_outer_c_theta = np.tile(np.sin(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.cos_outer_c_theta = np.tile(np.cos(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.sin_outer_t_theta = np.tile(np.sin(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.cos_outer_t_theta = np.tile(np.cos(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.inner_theta = self.Pi[:, 2] self.sin_inner_c_theta = np.tile(np.sin(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.cos_inner_c_theta = np.tile(np.cos(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.sin_inner_t_theta = np.tile(np.sin(self.inner_theta), (self.n_t_controls, 1)).T.flatten() self.cos_inner_t_theta = np.tile(np.cos(self.inner_theta), (self.n_t_controls, 1)).T.flatten() #calculate derivatives #in polar coordinates self.dPo_bar_xqdCc = np.array(self.x_mag * self.bsc_o.B.flatten()) self.dPo_bar_rqdCc = np.array(self.r_mag * self.bsc_o.B.flatten()) self.dPi_bar_xqdCc = np.array(self.x_mag * self.bsc_i.B.flatten()) self.dPi_bar_rqdCc = np.array(self.r_mag * self.bsc_i.B.flatten()) self.dPo_bar_rqdCt = np.array(self.r_mag * self.bst_o.B.flatten()) self.dPi_bar_rqdCt = -1 * np.array(self.r_mag * self.bst_i.B.flatten()) #Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = self.dPo_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYoqdCc = (self.dPo_bar_rqdCc * self.sin_outer_c_theta).reshape( -1, self.n_c_controls) self.dZoqdCc = (self.dPo_bar_rqdCc * self.cos_outer_c_theta).reshape( -1, self.n_c_controls) self.dXiqdCc = self.dPi_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYiqdCc = (self.dPi_bar_rqdCc * self.sin_inner_c_theta).reshape( -1, self.n_c_controls) self.dZiqdCc = (self.dPi_bar_rqdCc * self.cos_inner_c_theta).reshape( -1, self.n_c_controls) self.dYoqdCt = (self.dPo_bar_rqdCt * self.sin_outer_t_theta).reshape( -1, self.n_t_controls) self.dZoqdCt = (self.dPo_bar_rqdCt * self.cos_outer_t_theta).reshape( -1, self.n_t_controls) self.dYiqdCt = (self.dPi_bar_rqdCt * self.sin_inner_t_theta).reshape( -1, self.n_t_controls) self.dZiqdCt = (self.dPi_bar_rqdCt * self.cos_inner_t_theta).reshape( -1, self.n_t_controls) def copy(self): return copy.deepcopy(self) def plot_geom(self, ax, initial_color='g', ffd_color='k'): if initial_color: ax.scatter(self.Po[:, 0], self.Po[:, 1], c=initial_color, s=50, label="%s initial geom" % self.name) ax.scatter(self.Pi[:, 0], self.Pi[:, 1], c=initial_color, s=50) ax.plot(self.Po[:, 0], self.Po[:, 1], c=initial_color) ax.plot(self.Pi[:, 0], self.Pi[:, 1], c=initial_color) if ffd_color: ax.scatter(self.Po_bar[:, 0], self.Po_bar[:, 1], c=ffd_color, s=50, label="%s ffd geom" % self.name) ax.scatter(self.Pi_bar[:, 0], self.Pi_bar[:, 1], c=ffd_color, s=50) ax.plot(self.Po_bar[:, 0], self.Po_bar[:, 1], c=ffd_color) ax.plot(self.Pi_bar[:, 0], self.Pi_bar[:, 1], c=ffd_color) def plot_centerline_spline(self, ax, point_color='r', line_color='b'): ax.scatter(self.Cc_bar[:, 0], self.Cc_bar[:, 1], c=point_color, s=50, label="%s Centerline Control Points" % self.name) map_points = self.bsc_o(np.linspace(0, 1, 100)) ax.plot(map_points[:, 0], map_points[:, 1], label="Centerline b-spline Curve", c=line_color) def plot_thickness_spline(self, ax, point_color='r', line_color='b'): ax.scatter(self.Ct_bar[:, 0], self.Ct_bar[:, 1], c=point_color, s=50, label="%s Thickness Control Points" % self.name) map_points = self.bst_o(np.linspace(0, 1, 100)) ax.plot(map_points[:, 0], map_points[:, 1], label="Thickness b-spline Curve", c=line_color) def deform(self, delta_Cc, delta_Ct): """returns new point locations for the given motion of the control points for center-line and thickness""" self.delta_Cc = delta_Cc self.delta_Cc[:, 0] *= self.x_mag self.Cc_bar = self.Cc + self.delta_Cc delta_Pc_o = self.bsc_o.calc(self.Cc_bar) delta_Pc_i = self.bsc_i.calc(self.Cc_bar) self.delta_Ct = delta_Ct self.Ct_bar = self.Ct + self.delta_Ct delta_Pt_o = self.bst_o.calc(self.Ct_bar) delta_Pt_i = self.bst_i.calc(self.Ct_bar) self.Po_bar = self.Po.copy() self.Pi_bar = self.Pi.copy() self.Po_bar[:, 0] = delta_Pc_o[:, 0] self.Po_bar[:, 1] = self.Po[:, 1] + self.r_mag * (delta_Pc_o[:, 1] + delta_Pt_o[:, 1]) self.Pi_bar[:, 0] = delta_Pc_i[:, 0] self.Pi_bar[:, 1] = self.Pi[:, 1] + self.r_mag * (delta_Pc_i[:, 1] - delta_Pt_i[:, 1]) #transform to cartesian coordinates self.outer_coords = Coordinates(self.Po_bar, cartesian=False) self.inner_coords = Coordinates(self.Pi_bar, cartesian=False) #Perform axial roation of 2-d polar coordiantes #outer surface self.Po_bar_cart = self.outer_coords.cartesian self.Xo = self.Po_bar_cart[:, 0] self.Yo = self.Po_bar_cart[:, 1] self.Zo = self.Po_bar_cart[:, 2] self.outer_stl.update_points(self.Po_bar_cart) #inner surface self.Pi_bar_cart = self.inner_coords.cartesian self.Xi = self.Po_bar_cart[:, 0] self.Yi = self.Po_bar_cart[:, 1] self.Zi = self.Po_bar_cart[:, 2] self.inner_stl.update_points(self.Pi_bar_cart) return self.Po_bar, self.Pi_bar
class Body(object): """FFD class for solid bodies which only have one surface""" def __init__(self, stl, controls, name="body", r_ref=None, x_ref=None): """stl must be an STL object""" self.stl = stl geom_points = stl.points self.coords = Coordinates(geom_points, cartesian=True) self.P = self.coords.cylindrical self.P_cart = self.coords.cartesian self.P_bar = geom_points.copy() # just initialization if isinstance(controls, int): X = geom_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, controls) C_r = np.zeros((controls,)) control_points = np.array(zip(C_x, C_r)) self.C = control_points self.n_controls = controls else: self.C = controls self.n_controls = len(controls) self.C_bar = self.C.copy() self.delta_C = np.zeros(self.C.shape) self.bs = Bspline(self.C, geom_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10 ** np.floor(np.log10(np.average(geom_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and(abs(geom_points[:, 2]) < 2e-6, geom_points[:, 1] > 0) points = geom_points[indecies] self.r_mag = 10 ** np.floor( np.log10(np.average(points[:, 1])) ) # grab the order of magnitude of the average # for revolution of 2-d profile # self.n_theta = 20 # sgrab the theta values from the points self.Theta = self.P[:, 2] # this is too complex. shouldn't need to tile, then flatten later. self.sin_theta = np.tile(np.sin(self.Theta), (self.n_controls, 1)).T.flatten() self.cos_theta = np.tile(np.cos(self.Theta), (self.n_controls, 1)).T.flatten() # self.sin_theta = np.tile(np.sin(self.Theta),self.n_controls) # self.cos_theta = np.tile(np.cos(self.Theta),self.n_controls) # calculate derivatives # in polar coordinates self.dP_bar_xqdC = np.array(self.x_mag * self.bs.B.flatten()) self.dP_bar_rqdC = np.array(self.r_mag * self.bs.B.flatten()) # Project Polar derivatives into revolved cartisian coordinates self.dXqdC = self.dP_bar_xqdC.reshape(-1, self.n_controls) self.dYqdC = (self.dP_bar_rqdC * self.sin_theta).reshape(-1, self.n_controls) self.dZqdC = (self.dP_bar_rqdC * self.cos_theta).reshape(-1, self.n_controls) def copy(self): return copy.deepcopy(self) def deform(self, delta_C): """returns new point locations for the given motion of the control points""" self.delta_C = delta_C self.delta_C[:, 0] = self.delta_C[:, 0] * self.x_mag self.C_bar = self.C + self.delta_C delta_P = self.bs.calc(self.C_bar) self.P_bar = self.P.copy() self.P_bar[:, 0] = delta_P[:, 0] self.P_bar[:, 1] = self.P[:, 1] + self.r_mag * delta_P[:, 1] # transform to cartesian coordinates self.coords = Coordinates(self.P_bar, cartesian=False) self.P_bar_cart = self.coords.cartesian self.Xo = self.P_bar_cart[:, 0] self.Yo = self.P_bar_cart[:, 1] self.Zo = self.P_bar_cart[:, 2] self.stl.update_points(self.P_bar_cart) return self.P_bar
def __init__(self, outer_stl, inner_stl, center_line_controls, thickness_controls, name='shell', r_ref=None, x_ref=None): self.outer_stl = outer_stl self.inner_stl = inner_stl outer_points = outer_stl.points inner_points = inner_stl.points self.n_outer = len(outer_points) self.n_inner = len(inner_points) self.outer_coords = Coordinates(outer_points, cartesian=True) self.inner_coords = Coordinates(inner_points, cartesian=True) self.Po = self.outer_coords.cylindrical self.Pi = self.inner_coords.cylindrical self.Po_cart = self.outer_coords.cartesian self.Pi_cart = self.inner_coords.cartesian #just initialization for array size self.Po_bar = outer_points.copy() self.Pi_bar = inner_points.copy() self.name = name if isinstance(center_line_controls, int): X = outer_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, center_line_controls) C_r = np.zeros((center_line_controls, )) control_points = np.array(zip(C_x, C_r)) self.Cc = control_points self.n_c_controls = center_line_controls else: self.Cc = center_line_controls self.n_c_controls = len(center_line_controls) self.Cc_bar = self.Cc.copy() self.delta_Cc = np.zeros(self.Cc.shape) if isinstance(thickness_controls, int): X = inner_points[:, 0] x_max = np.max(X) x_min = np.min(X) C_x = np.linspace(x_min, x_max, thickness_controls) C_r = np.zeros((thickness_controls, )) control_points = np.array(zip(C_x, C_r)) self.Ct = control_points self.n_t_controls = thickness_controls else: self.Ct = thickness_controls self.n_t_controls = len(thickness_controls) self.Ct_bar = self.Ct.copy() self.delta_Ct = np.zeros(self.Ct.shape) self.bsc_o = Bspline(self.Cc, outer_points) self.bsc_i = Bspline(self.Cc, inner_points) self.bst_o = Bspline(self.Ct, outer_points) self.bst_i = Bspline(self.Ct, inner_points) self.name = name if x_ref is not None: self.x_mag = float(x_ref) else: self.x_mag = 10**np.floor(np.log10(np.average(outer_points[:, 0]))) if r_ref is not None: self.r_mag = float(r_ref) else: indecies = np.logical_and( abs(outer_points[:, 2]) < 2E-6, outer_points[:, 1] > 0) points = outer_points[indecies] self.r_mag = 10**np.floor(np.log10(np.average( points[:, 1]))) #grab the order of magnitude of the average self.outer_theta = self.Po[:, 2] self.sin_outer_c_theta = np.tile(np.sin(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.cos_outer_c_theta = np.tile(np.cos(self.outer_theta), (self.n_c_controls, 1)).T.flatten() self.sin_outer_t_theta = np.tile(np.sin(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.cos_outer_t_theta = np.tile(np.cos(self.outer_theta), (self.n_t_controls, 1)).T.flatten() self.inner_theta = self.Pi[:, 2] self.sin_inner_c_theta = np.tile(np.sin(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.cos_inner_c_theta = np.tile(np.cos(self.inner_theta), (self.n_c_controls, 1)).T.flatten() self.sin_inner_t_theta = np.tile(np.sin(self.inner_theta), (self.n_t_controls, 1)).T.flatten() self.cos_inner_t_theta = np.tile(np.cos(self.inner_theta), (self.n_t_controls, 1)).T.flatten() #calculate derivatives #in polar coordinates self.dPo_bar_xqdCc = np.array(self.x_mag * self.bsc_o.B.flatten()) self.dPo_bar_rqdCc = np.array(self.r_mag * self.bsc_o.B.flatten()) self.dPi_bar_xqdCc = np.array(self.x_mag * self.bsc_i.B.flatten()) self.dPi_bar_rqdCc = np.array(self.r_mag * self.bsc_i.B.flatten()) self.dPo_bar_rqdCt = np.array(self.r_mag * self.bst_o.B.flatten()) self.dPi_bar_rqdCt = -1 * np.array(self.r_mag * self.bst_i.B.flatten()) #Project Polar derivatives into revolved cartisian coordinates self.dXoqdCc = self.dPo_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYoqdCc = (self.dPo_bar_rqdCc * self.sin_outer_c_theta).reshape( -1, self.n_c_controls) self.dZoqdCc = (self.dPo_bar_rqdCc * self.cos_outer_c_theta).reshape( -1, self.n_c_controls) self.dXiqdCc = self.dPi_bar_xqdCc.reshape(-1, self.n_c_controls) self.dYiqdCc = (self.dPi_bar_rqdCc * self.sin_inner_c_theta).reshape( -1, self.n_c_controls) self.dZiqdCc = (self.dPi_bar_rqdCc * self.cos_inner_c_theta).reshape( -1, self.n_c_controls) self.dYoqdCt = (self.dPo_bar_rqdCt * self.sin_outer_t_theta).reshape( -1, self.n_t_controls) self.dZoqdCt = (self.dPo_bar_rqdCt * self.cos_outer_t_theta).reshape( -1, self.n_t_controls) self.dYiqdCt = (self.dPi_bar_rqdCt * self.sin_inner_t_theta).reshape( -1, self.n_t_controls) self.dZiqdCt = (self.dPi_bar_rqdCt * self.cos_inner_t_theta).reshape( -1, self.n_t_controls)
## Escribo bien los nodos y los pesos para las integrales en r r_nodos = np.array([]); wr_pesos = np.array([]); for i in range(N_intervalos_r+1): aux_x = 0.5*(knots_r[i+grado+1]-knots_r[i+grado])*x + 0.5*(knots_r[i+grado+1]+knots_r[i+grado]); aux_w = 0.5*(knots_r[i+grado+1]-knots_r[i+grado])*w; r_nodos = np.hstack((r_nodos, aux_x)); wr_pesos = np.hstack((wr_pesos, aux_w)); w_pesos = wr_pesos wr_pesos = np.tile(wr_pesos, (N_splines_r-1, 1)); r_nodos2 = np.tile(r_nodos, (N_splines_r-1, 1)); ## B-splines en la coordenada r basis = Bspline(knots_r, grado); ## Calculo la matriz con los bsplines y sus derivadas en r bsr = [basis._Bspline__basis(i, basis.p) for i in r_nodos]; # evaluo los bsplines dbsr = [basis.d(i) for i in r_nodos]; # evaluo las derivadas de los bsplines bsr = np.array(bsr) bsr = bsr[:,0:N_splines_r-1] dbsr = np.array(dbsr) dbsr = dbsr[:,0:N_splines_r-1] ## Matriz de solapamiento en r Sr = np.dot(np.transpose(bsr), (np.transpose(r_nodos2)*np.transpose(wr_pesos)*bsr)); # Sr = np.array([[Sr[i][j] for i in range(N_splines_r-1)] for j in range(N_splines_r-1)]); ## Matriz de energia cinetica en r
def __init__(self, cambCP, p=2): self._cambCP = cambCP self._cambDef = cambCP.getCambDef() self._p = p self._camb = Bspline(cambCP(), p=p) self._derCamb = DerBspline(self._camb, kth=1)