def trefftz_plane_velocities(self, pnts: MatrixVector, betx: float = 1.0, bety: float = 1.0, betz: float = 1.0): # Trailing Vortex A agcs = self.relative_mach(pnts, self.grda, betx=betx, bety=bety, betz=betz) dirxa = -self.diro dirza = self.nrm dirya = dirza**dirxa alcs = MatrixVector(agcs * dirxa, agcs * dirya, agcs * dirza) alcs.x = zeros(alcs.shape, dtype=float) axx = MatrixVector(alcs.x, -alcs.z, alcs.y) am2 = square(alcs.y) + square(alcs.z) chkam2 = absolute(am2) < tol am2r = zeros(pnts.shape, dtype=float) reciprocal(am2, where=logical_not(chkam2), out=am2r) faca = -1.0 veldl = elementwise_multiply(axx, am2r) * faca veldl.x[chkam2] = 0.0 veldl.y[chkam2] = 0.0 veldl.z[chkam2] = 0.0 dirxi = Vector(dirxa.x, dirya.x, dirza.x) diryi = Vector(dirxa.y, dirya.y, dirza.y) dirzi = Vector(dirxa.z, dirya.z, dirza.z) velda = MatrixVector(veldl * dirxi, veldl * diryi, veldl * dirzi) * faca # Trailing Vortex B bgcs = self.relative_mach(pnts, self.grdb, betx=betx, bety=bety, betz=betz) dirxb = self.diro dirzb = self.nrm diryb = dirzb**dirxb blcs = MatrixVector(bgcs * dirxb, bgcs * diryb, bgcs * dirzb) blcs.x = zeros(blcs.shape, dtype=float) bxx = MatrixVector(blcs.x, -blcs.z, blcs.y) bm2 = square(blcs.y) + square(blcs.z) chkbm2 = absolute(bm2) < tol bm2r = zeros(pnts.shape, dtype=float) reciprocal(bm2, where=logical_not(chkbm2), out=bm2r) facb = 1.0 veldl = elementwise_multiply(bxx, bm2r) * facb veldl.x[chkbm2] = 0.0 veldl.y[chkbm2] = 0.0 veldl.z[chkbm2] = 0.0 dirxi = Vector(dirxb.x, diryb.x, dirzb.x) diryi = Vector(dirxb.y, diryb.y, dirzb.y) dirzi = Vector(dirxb.z, diryb.z, dirzb.z) veldb = MatrixVector(veldl * dirxi, veldl * diryi, veldl * dirzi) * facb # Add Together veld = velda + veldb return veld / twoPi
def vel_doublet_matrix(ov, om, faco): ov = faco * ov oxx = MatrixVector(zeros(ov.shape), -ov.z, ov.y) oxxm = oxx.return_magnitude() chko = (oxxm == 0.0) velol = elementwise_divide(oxx, multiply(om, om - ov.x)) velol.x[chko] = 0.0 velol.y[chko] = 0.0 velol.z[chko] = 0.0 return velol
def velocity_matrix(ra: MatrixVector, rb: MatrixVector, rc: MatrixVector, betm: float = 1.0, tol: float = 1e-12): if ra.shape != rb.shape: return ValueError() numi = rc.shape[0] numj = ra.shape[1] ra = ra.repeat(numi, axis=0) rb = rb.repeat(numi, axis=0) rc = rc.repeat(numj, axis=1) a = rc - ra b = rc - rb a.x = a.x / betm b.x = b.x / betm am = a.return_magnitude() bm = b.return_magnitude() # Velocity from Bound Vortex adb = elementwise_dot_product(a, b) abm = multiply(am, bm) dm = multiply(abm, abm + adb) axb = elementwise_cross_product(a, b) axbm = axb.return_magnitude() chki = (axbm == 0.0) chki = logical_and(axbm >= -tol, axbm <= tol) veli = elementwise_multiply(axb, divide(am + bm, dm)) veli.x[chki] = 0.0 veli.y[chki] = 0.0 veli.z[chki] = 0.0 # Velocity from Trailing Vortex A axx = MatrixVector(zeros(a.shape, dtype=float), a.z, -a.y) axxm = axx.return_magnitude() chka = (axxm == 0.0) vela = elementwise_divide(axx, multiply(am, am - a.x)) vela.x[chka] = 0.0 vela.y[chka] = 0.0 vela.z[chka] = 0.0 # Velocity from Trailing Vortex B bxx = MatrixVector(zeros(b.shape, dtype=float), b.z, -b.y) bxxm = bxx.return_magnitude() chkb = (bxxm == 0.0) velb = elementwise_divide(bxx, multiply(bm, bm - b.x)) velb.x[chkb] = 0.0 velb.y[chkb] = 0.0 velb.z[chkb] = 0.0 return veli, vela, velb
def vel_trailing_doublet_matrix(ov, om, faco): ov: MatrixVector = faco * ov oxx = MatrixVector(zeros(ov.shape), -ov.z, ov.y) oxxm = oxx.return_magnitude() chko = absolute(oxxm) < tol den = multiply(om, om - ov.x) chkd = absolute(den) < tol denr = zeros(ov.shape, dtype=float) reciprocal(den, where=logical_not(chkd), out=denr) velol = elementwise_multiply(oxx, denr) velol.x[chko] = 0.0 velol.y[chko] = 0.0 velol.z[chko] = 0.0 return velol
def fetch_pids_ttol(pnts: MatrixVector, psys: PanelSystem, ztol: float=0.01, ttol: float=0.1): shp = pnts.shape pnts = pnts.reshape((-1, 1)) numpnt = pnts.shape[0] numpnl = len(psys.pnls) pidm = zeros((1, numpnl), dtype=int) wintm = zeros((numpnt, numpnl), dtype=bool) abszm = zeros((numpnt, numpnl), dtype=float) for pnl in psys.pnls.values(): pidm[0, pnl.ind] = pnl.pid wintm[:, pnl.ind], abszm[:, pnl.ind] = pnl.within_and_absz_ttol(pnts[:, 0], ttol=ttol) abszm[wintm is False] = float('inf') minm = argmin(abszm, axis=1) minm = array(minm).flatten() pidm = array(pidm).flatten() pids = pidm[minm] pids = matrix([pids], dtype=int).transpose() indp = arange(numpnt) minz = array(abszm[indp, minm]).flatten() minz = matrix([minz], dtype=float).transpose() chkz = minz < ztol pids[logical_not(chkz)] = 0 pids = pids.reshape(shp) chkz = chkz.reshape(shp) return pids, chkz
def phi_doublet_matrix(vecs: MatrixVector, sgnz: matrix): mags = vecs.return_magnitude() chkm = mags < tol chky = absolute(vecs.y) < tol vecs.y[chky] = 0.0 ms = zeros(mags.shape, dtype=float) divide(vecs.x, vecs.y, where=logical_not(chky), out=ms) ths = arctan(ms) ths[chky] = piby2 ts = zeros(mags.shape, dtype=float) divide(vecs.z, mags, where=logical_not(chkm), out=ts) gs = multiply(ms, ts) Js = arctan(gs) Js[chky] = piby2 phids = Js - multiply(sgnz, ths) return phids, mags
def phi_doublet_matrix(vecs: MatrixVector, rls: MatrixVector, sgnz: matrix): mags = vecs.return_magnitude() ms = divide(vecs.x, rls.y) ths = arctan(ms) ths[rls.y == 0.0] = piby2 gs = multiply(ms, divide(rls.z, mags)) Js = arctan(gs) Js[rls.y == 0.0] = piby2 phids = Js - multiply(sgnz, ths) return phids, mags
def __sub__(self, obj): from pygeom.matrix3d import MatrixVector if isinstance(obj, Vector): x = self.x-obj.x y = self.y-obj.y z = self.z-obj.z return Vector(x, y, z) elif isinstance(obj, MatrixVector): x = self.x-obj.x y = self.y-obj.y z = self.z-obj.z return MatrixVector(x, y, z)
def __pow__(self, obj): from pygeom.matrix3d import MatrixVector if isinstance(obj, Vector): x = self.y*obj.z-self.z*obj.y y = self.z*obj.x-self.x*obj.z z = self.x*obj.y-self.y*obj.x return Vector(x, y, z) elif isinstance(obj, MatrixVector): x = self.y*obj.z-self.z*obj.y y = self.z*obj.x-self.x*obj.z z = self.x*obj.y-self.y*obj.x return MatrixVector(x, y, z)
def trefftz_plane_velocities(self, pnts: MatrixVector): rls = self.points_to_local(pnts) rls.x = zeros(rls.shape, dtype=float) # ro = Vector(0.0, self.grdo.y, self.grdo.z) # o = rls-ro oxx = MatrixVector(rls.x, -rls.z, rls.y) om2 = square(rls.y) + square(rls.z) chkom2 = (absolute(om2) < tol) veldl = elementwise_divide(oxx, om2) * self.faco veldl.x[chkom2] = 0.0 veldl.y[chkom2] = 0.0 veldl.z[chkom2] = 0.0 veld = self.vectors_to_global(veldl) * self.faco return veld / twoPi
def __rmul__(self, obj): from numpy.matlib import matrix from pygeom.matrix3d import MatrixVector if isinstance(obj, (Vector, MatrixVector)): return self.x*obj.x+self.y*obj.y+self.z*obj.z elif isinstance(obj, matrix): x = obj*self.x y = obj*self.y z = obj*self.z return MatrixVector(x, y, z) else: x = obj*self.x y = obj*self.y z = obj*self.z return Vector(x, y, z)
def within_and_absz_ttol(self, pnts: MatrixVector, ttol: float = 0.1): shp = pnts.shape pnts = pnts.reshape((-1, 1)) rgcs = pnts - self.pnto wint = full(pnts.shape, False) absz = full(pnts.shape, float('inf')) for i in range(self.num): dirx = self.dirxab[0, i] diry = self.diryab[0, i] dirz = self.dirzab[0, i] xy1 = ones((pnts.shape[0], 3), dtype=float) xy1[:, 1] = rgcs * dirx xy1[:, 2] = rgcs * diry t123 = xy1 * self.baryinv[i].transpose() mint = t123.min(axis=1) chk = mint > -ttol wint[chk] = True abszi = absolute(rgcs * dirz) abszi[logical_not(chk)] = float('inf') absz = minimum(absz, abszi) wint = wint.reshape(shp) absz = absz.reshape(shp) return wint, absz
def influence_coefficients(self, pnts: MatrixVector, incvel: bool=True, betx: float=1.0, bety: float=1.0, betz: float=1.0, checktol: bool=False): grdm = self.mach_grids(betx=betx, bety=bety, betz=betz) vecab = self.edge_vector(grdm) vecaxb = self.edge_cross(grdm) dirxab = vecab.to_unit() dirzab = vecaxb.to_unit() diryab = elementwise_cross_product(dirzab, dirxab) nrm = vecaxb.sum().to_unit() rgcs = self.relative_mach(pnts, self.pnto, betx=betx, bety=bety, betz=betz) locz = rgcs*nrm sgnz = ones(locz.shape, dtype=float) sgnz[locz <= 0.0] = -1.0 vecgcs = [] for i in range(self.num): vecgcs.append(self.relative_mach(pnts, self.grds[i], betx=betx, bety=bety, betz=betz)) phid = zeros(pnts.shape, dtype=float) phis = zeros(pnts.shape, dtype=float) if incvel: veld = zero_matrix_vector(pnts.shape, dtype=float) vels = zero_matrix_vector(pnts.shape, dtype=float) for i in range(self.num): # Edge Length dab = vecab[0, i].return_magnitude() # Local Coordinate System dirx = dirxab[0, i] diry = diryab[0, i] dirz = dirzab[0, i] # Vector A in Local Coordinate System veca = vecgcs[i-1] alcs = MatrixVector(veca*dirx, veca*diry, veca*dirz) if checktol: alcs.x[absolute(alcs.x) < tol] = 0.0 alcs.y[absolute(alcs.y) < tol] = 0.0 alcs.z[absolute(alcs.z) < tol] = 0.0 # Vector A Doublet Velocity Potentials phida, amag = phi_doublet_matrix(alcs, sgnz) # Vector B in Local Coordinate System vecb = vecgcs[i] blcs = MatrixVector(vecb*dirx, vecb*diry, vecb*dirz) if checktol: blcs.x[absolute(blcs.x) < tol] = 0.0 blcs.y[absolute(blcs.y) < tol] = 0.0 blcs.z[absolute(blcs.z) < tol] = 0.0 # Vector B Doublet Velocity Potentials phidb, bmag = phi_doublet_matrix(blcs, sgnz) # Edge Doublet Velocity Potentials phidi = phida - phidb # Edge Source Velocity Potentials phisi, Qab = phi_source_matrix(amag, bmag, dab, alcs, phidi) # Add Edge Velocity Potentials phid += phidi phis += phisi # Calculate Edge Velocities if incvel: # Velocities in Local Coordinate System veldi = vel_doublet_matrix(alcs, amag, blcs, bmag) velsi = vel_source_matrix(Qab, alcs, phidi) # Transform to Global Coordinate System and Add dirxi = Vector(dirx.x, diry.x, dirz.x) diryi = Vector(dirx.y, diry.y, dirz.y) dirzi = Vector(dirx.z, diry.z, dirz.z) veld += MatrixVector(veldi*dirxi, veldi*diryi, veldi*dirzi) vels += MatrixVector(velsi*dirxi, velsi*diryi, velsi*dirzi) phid = phid/fourPi phis = phis/fourPi if incvel: veld = veld/fourPi vels = vels/fourPi output = phid, phis, veld, vels else: output = phid, phis return output
def doublet_influence_coefficients(self, pnts: MatrixVector, incvel: bool = True, betx: float = 1.0, bety: float = 1.0, betz: float = 1.0, checktol: bool = False): vecab = Vector(self.vecab.x / betx, self.vecab.y / bety, self.vecab.z / betz) dirxab = vecab.to_unit() dirzab = Vector(self.nrm.x, self.nrm.y, self.nrm.z) diryab = dirzab**dirxab agcs = self.relative_mach(pnts, self.grda, betx=betx, bety=bety, betz=betz) bgcs = self.relative_mach(pnts, self.grdb, betx=betx, bety=bety, betz=betz) locz = agcs * self.nrm sgnz = ones(locz.shape, dtype=float) sgnz[locz <= 0.0] = -1.0 phid = zeros(pnts.shape, dtype=float) if incvel: veld = zero_matrix_vector(pnts.shape, dtype=float) # Vector A in Local Coordinate System alcs = MatrixVector(agcs * dirxab, agcs * diryab, agcs * dirzab) if checktol: alcs.x[absolute(alcs.x) < tol] = 0.0 alcs.y[absolute(alcs.y) < tol] = 0.0 alcs.z[absolute(alcs.z) < tol] = 0.0 # Vector A Doublet Velocity Potentials phida, amag = phi_doublet_matrix(alcs, sgnz) # Vector B in Local Coordinate System blcs = MatrixVector(bgcs * dirxab, bgcs * diryab, bgcs * dirzab) if checktol: blcs.x[absolute(blcs.x) < tol] = 0.0 blcs.y[absolute(blcs.y) < tol] = 0.0 blcs.z[absolute(blcs.z) < tol] = 0.0 # Vector B Doublet Velocity Potentials phidb, bmag = phi_doublet_matrix(blcs, sgnz) # Edge Doublet Velocity Potentials phidi = phida - phidb # Add Edge Velocity Potentials phid += phidi if incvel: # Bound Edge Velocities in Local Coordinate System veldi = vel_doublet_matrix(alcs, amag, blcs, bmag) # Transform to Global Coordinate System and Add dirxi = Vector(dirxab.x, diryab.x, dirzab.x) diryi = Vector(dirxab.y, diryab.y, dirzab.y) dirzi = Vector(dirxab.z, diryab.z, dirzab.z) veld += MatrixVector(veldi * dirxi, veldi * diryi, veldi * dirzi) # Trailing Edge A Coordinate Transformation dirxa = self.diro dirza = self.nrm dirya = -dirza**dirxa alcs = MatrixVector(agcs * dirxa, agcs * dirya, agcs * dirza) # Trailing Edge A Velocity Potential phida, amag = phi_doublet_matrix(alcs, sgnz) phidt = phi_trailing_doublet_matrix(alcs, sgnz) phidi = phida + phidt # Add Trailing Edge A Velocity Potentials phid += phidi # Trailing Edge B Coordinate Transformation if incvel: # Trailing Edge A Velocities in Local Coordinate System veldi = vel_trailing_doublet_matrix(alcs, amag, 1.0) # Transform to Global Coordinate System and Add dirxi = Vector(dirxa.x, dirya.x, dirza.x) diryi = Vector(dirxa.y, dirya.y, dirza.y) dirzi = Vector(dirxa.z, dirya.z, dirza.z) veld += MatrixVector(veldi * dirxi, veldi * diryi, veldi * dirzi) # Trailing Edge B Coordinate Transformation dirxb = self.diro dirzb = self.nrm diryb = dirzb**dirxb blcs = MatrixVector(bgcs * dirxb, bgcs * diryb, bgcs * dirzb) # Trailing Edge B Velocity Potential phidb, bmag = phi_doublet_matrix(blcs, sgnz) phidt = phi_trailing_doublet_matrix(blcs, sgnz) phidi = phidb + phidt # Add Trailing Edge B Velocity Potentials phid += phidi if incvel: # Trailing Edge B Velocities in Local Coordinate System veldi = vel_trailing_doublet_matrix(blcs, bmag, 1.0) # Transform to Global Coordinate System and Add dirxi = Vector(dirxb.x, diryb.x, dirzb.x) diryi = Vector(dirxb.y, diryb.y, dirzb.y) dirzi = Vector(dirxb.z, diryb.z, dirzb.z) veld += MatrixVector(veldi * dirxi, veldi * diryi, veldi * dirzi) # Factors and Outputs phid = phid / fourPi if incvel: veld = veld / fourPi output = phid, veld else: output = phid return output
def vectors_to_global(self, vecs: MatrixVector): dirx = Vector(self.dirx.x, self.diry.x, self.dirz.x) diry = Vector(self.dirx.y, self.diry.y, self.dirz.y) dirz = Vector(self.dirx.z, self.diry.z, self.dirz.z) return MatrixVector(vecs * dirx, vecs * diry, vecs * dirz)
def points_to_local(self, pnts: MatrixVector, betx: float = 1.0): vecs = pnts - self.pntc if betx != 1.0: vecs.x = vecs.x / betx return MatrixVector(vecs * self.dirx, vecs * self.diry, vecs * self.dirz)