sm.symbols('zeta01_x,zeta02_x,zeta01_y,zeta02_y', real=True) V0_x,V0_y=sm.symbols('V0_x,V0_y', real=True) V0=smarr.MutableDenseNDimArray([V0_x,V0_y]) Kskew2D=smarr.MutableDenseNDimArray([[0,-1],[1,0]]) # Position vectors Zeta01=smarr.MutableDenseNDimArray([zeta01_x,zeta01_y]) Zeta02=smarr.MutableDenseNDimArray([zeta02_x,zeta02_y]) # define order of derivation ZetaAllList=[zeta01_x,zeta02_x,zeta01_y,zeta02_y] # Delta vector (and derivative) Dzeta=Zeta02-Zeta01 Dzeta_unit=Dzeta/sm.sqrt(linfunc.scalar_product(Dzeta,Dzeta)) #Dzeta_unit=Dzeta_unit.simplify() # Normal Norm=linfunc.matrix_product(Kskew2D,Dzeta_unit) Norm=linfunc.simplify(Norm) ### check norm assert linfunc.scalar_product(Norm,Dzeta).simplify()==0, 'Norm is wrong' assert linfunc.scalar_product(Norm,Dzeta_unit).simplify()==0, 'Norm is wrong' assert linfunc.scalar_product(Norm,Norm).simplify()==1, 'Normal is not unit length' # Normal velocity Vperp=linfunc.scalar_product(Norm,V0)
dRA = sm.derive_by_array(RA, [ZetaP, ZetaA, ZetaB]) dRB = sm.derive_by_array(RB, [ZetaP, ZetaA, ZetaB]) dRAB = sm.derive_by_array(RAB, [ZetaP, ZetaA, ZetaB]) ################################################################################ ### redefine R02,R13 ra_x, ra_y, ra_z = sm.symbols('ra_x ra_y ra_z', real=True) rb_x, rb_y, rb_z = sm.symbols('rb_x rb_y rb_z', real=True) rab_x, rab_y, rab_z = sm.symbols('rab_x rab_y rab_z', real=True) RA = smarr.MutableDenseNDimArray([ra_x, ra_y, ra_z]) RB = smarr.MutableDenseNDimArray([rb_x, rb_y, rb_z]) RAB = smarr.MutableDenseNDimArray([rab_x, rab_y, rab_z]) Vcross = linfunc.cross_product(RA, RB) Vcross_sq = linfunc.scalar_product(Vcross, Vcross) #Vcross_norm=linfunc.norm2(Vcross) #Vcross_unit=Vcross/Vcross_norm RA_unit = RA / linfunc.norm2(RA) RB_unit = RB / linfunc.norm2(RB) #Q=1/4/sm.pi*Vcross_unit*linfunc.scalar_product(RAB,(RA_unit-RB_unit)) Q = Vcross * linfunc.scalar_product(RAB, (RA_unit - RB_unit)) / Vcross_sq dQ = sm.derive_by_array(Q, [RA, RB, RAB]) ##### shorted equation ra_norm, rb_norm = sm.symbols('ra_norm rb_norm') dQshort = dQ.copy() dQshort = dQshort.subs(sm.sqrt(ra_x**2 + ra_y**2 + ra_z**2), ra_norm) dQshort = dQshort.subs(sm.sqrt(rb_x**2 + rb_y**2 + rb_z**2), rb_norm)
U02 = smarr.MutableDenseNDimArray([u01_x, u01_y, u01_z]) U03 = smarr.MutableDenseNDimArray([u02_x, u02_y, u02_z]) U04 = smarr.MutableDenseNDimArray([u03_x, u03_y, u03_z]) ### velocity at collocation point uc_x, uc_y, uc_z = sm.symbols('uc_x uc_y uc_z', real=True) Uc = smarr.MutableDenseNDimArray([uc_x, uc_y, uc_z]) ### Compute normal to panel # see surface.AeroGridSurface.get_panel_normal R02 = Zeta02 - Zeta00 R13 = Zeta03 - Zeta01 Norm = linfunc.cross_product(R02, R13) Norm = Norm / linfunc.norm2(Norm) ### check norm assert linfunc.scalar_product(Norm, R02).simplify() == 0, 'Norm is wrong' assert linfunc.scalar_product(Norm, R13).simplify() == 0, 'Norm is wrong' assert linfunc.scalar_product( Norm, Norm).simplify() == 1, 'Normal is not unit length' ### Compute normal velocity at panel Unorm = linfunc.scalar_product(Norm, Uc) Unorm = sm.simplify(Unorm) ### Compute derivative dUnorm_dZeta = sm.derive_by_array(Unorm, [Zeta00, Zeta01, Zeta02, Zeta03]) #dUnorm_dZeta=linfunc.simplify(dUnorm_dZeta) ################################################################################ ### exploit combined derivatives ################################################################################
def Vind_segment(R, cf, g): BiotTerm = cf * g * R / linfunc.scalar_product(R, R) Qind = linfunc.matrix_product(Kskew2D, BiotTerm) return linfunc.simplify(Qind)
return linfunc.simplify(Qind) # Full vortex velocity Qind_vortex = Vind_segment(R01, CF, Gamma) - Vind_segment(R02, CF, Gamma) # Joukovski force Fjouk = -gamma_s * linfunc.matrix_product(Kskew2D, Qind_vortex) Fjouk = linfunc.simplify(Fjouk) ### Derivative Der = sm.derive_by_array(Fjouk, ZetaAllList).transpose() # 2x6 #Der=linfunc.simplify(Der) ### Verification BiotTerm_vortex = +CF*Gamma*R01/linfunc.scalar_product(R01,R01) \ -CF*Gamma*R02/linfunc.scalar_product(R02,R02) derBiotTerm = sm.derive_by_array(BiotTerm_vortex, ZetaAllList).transpose() derQind = linfunc.matrix_product(Kskew2D, derBiotTerm) Der2 = -gamma_s * linfunc.matrix_product(Kskew2D, derQind) check = linfunc.simplify(Der - Der2) assert linfunc.scalar_product(check, check) == 0, 'Derivatives are not the same' ################ we use Der2 as it has a shorter form ########################## Der = Der2 ### Shorten expressions R01_x, R01_y = sm.symbols('R01_x,R01_y', real=True) R02_x, R02_y = sm.symbols('R02_x,R02_y', real=True)
import linfunc # coordinates # a00,a01,a02=sm.symbols('a00 a01 a02', real=True) # a11,a12=sm.symbols('a11 a12', real=True) # a22=sm.symbols('a22', real=True) ##### derivative w.r.t. Ra,Rb due to cross-product # show derivative is symmetric ra_x, ra_y, ra_z = sm.symbols('ra_x ra_y ra_z', real=True) rb_x, rb_y, rb_z = sm.symbols('rb_x rb_y rb_z', real=True) RA = smarr.MutableDenseNDimArray([ra_x, ra_y, ra_z]) RB = smarr.MutableDenseNDimArray([rb_x, rb_y, rb_z]) Vcross = linfunc.cross_product(RA, RB) V2 = linfunc.scalar_product(Vcross, Vcross) V4 = V2 * V2 Dv = sm.zeros(3) for ii in range(3): Dv[ii, ii] += 1 / V2 for jj in range(3): Dv[ii, jj] += -2 / V4 * Vcross[ii] * Vcross[jj] DvRAskew = linfunc.matrix_product(Dv, linfunc.skew(RA)) DvRBskew = linfunc.matrix_product(Dv, linfunc.skew(RB)) # verify symetry print('Verify symmetry of Dv') for ii in range(3): for jj in range(ii + 1, 3): print('ii,jj:%d,%d' % (ii, jj))