def scalar_deriv(a, xList): '''Compute derivatives of a scalar w.r.t. a list of valirables''' Nx = len(xList) Der = [] for ii in range(Nx): Der.append(a.diff(xList[ii])) return smarr.MutableDenseNDimArray(Der)
def skew(Av): ''' Compute skew matrix of vector Av, such that: skew(Av)*Bv = Av x Bv ''' assert len(Av) == 3, 'Av must be a 3 elements array' ax, ay, az = Av[0], Av[1], Av[2] Askew = smarr.MutableDenseNDimArray([[0, -az, ay], [az, 0, -ax], [-ay, ax, 0]]) return Askew
def subs(Av, expr_old, expr_new): ''' Iteratively apply the subs method to each element of tensor. ''' Av_sub = [] if len(Av.shape) == 1: for ii in range(len(Av)): Av_sub.append(Av[ii].subs(expr_old, expr_new)) elif len(Av.shape) == 2: for ii in range(Av.shape[0]): row = [] for jj in range(Av.shape[1]): row.append(Av[ii, jj].subs(expr_old, expr_new)) Av_sub.append(row) else: raise NameError('Method not developed for 3D arrays!') return smarr.MutableDenseNDimArray(Av_sub)
def simplify(Av): ''' Simplify each element of matrix/array ''' Av_simple = [] if len(Av.shape) == 1: for ii in range(len(Av)): Av_simple.append(Av[ii].simplify()) elif len(Av.shape) == 2: for ii in range(Av.shape[0]): row = [] for jj in range(Av.shape[1]): row.append(Av[ii, jj].simplify()) Av_simple.append(row) else: raise NameError('Method not developed for 3D arrays!') return smarr.MutableDenseNDimArray(Av_simple)
''' import numpy as np import sympy as sm #import sympy.tensor as smtens import sympy.tensor.array as smarr import linfunc # 1,2 local index in the element. Node 1 is "ahead" Zeta01,Zeta02=sm.symbols('Zeta01 Zeta02', real=True) zeta01_x,zeta02_x,zeta01_y,zeta02_y=\ 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()
for ii in range(Nx): Der.append(a.diff(xList[ii])) return smarr.MutableDenseNDimArray(Der) if __name__ == '__main__': import numpy as np print('Verification matrix product:') # numerical matrix product Alist = [[1, 4], [2, 5], [7, 4], [1, 9]] Blist = [[5, 8, 4], [1, 9, 7]] Cref = np.dot(np.array(Alist), np.array(Blist)) Cref = smarr.MutableDenseNDimArray(list(Cref)) # symbolic matrix product Asm = smarr.Array(Alist) Bsm = smarr.Array(Blist) Csm = matrix_product(Asm, Bsm) Csm_simple = simplify(Csm) print(Csm_simple - Cref) print('Verification cross product:') for ii in range(3): for jj in range(3): Av = smarr.MutableDenseNDimArray([0, 0, 0]) Bv = smarr.MutableDenseNDimArray([0, 0, 0]) Av[ii] = 1 Bv[jj] = 1 Cv = cross_product(Av, Bv)
import numpy as np import sympy as sm import sympy.tensor.array as smarr import linfunc ##### Define symbols ### vertices vectors # coordinates zetaA_x, zetaA_y, zetaA_z = sm.symbols('zetaA_x,zetaA_y,zetaA_z', real=True) zetaB_x, zetaB_y, zetaB_z = sm.symbols('zetaB_x,zetaB_y,zetaB_z', real=True) zetaP_x, zetaP_y, zetaP_z = sm.symbols('zetaP_x,zetaP_y,zetaP_z', real=True) # vectors ZetaA, ZetaB, ZetaP = sm.symbols('ZetaA ZetaB ZetaP', real=True) ZetaA = smarr.MutableDenseNDimArray([zetaA_x, zetaA_y, zetaA_z]) ZetaB = smarr.MutableDenseNDimArray([zetaB_x, zetaB_y, zetaB_z]) ZetaP = smarr.MutableDenseNDimArray([zetaP_x, zetaP_y, zetaP_z]) ### Difference vectors RA = ZetaP - ZetaA RB = ZetaP - ZetaB RAB = ZetaB - ZetaA 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)
##### Define symbols ### vertices vectors # coordinates zeta00_x, zeta00_y, zeta00_z = sm.symbols('zeta00_x,zeta00_y,zeta00_z', real=True) zeta01_x, zeta01_y, zeta01_z = sm.symbols('zeta01_x,zeta01_y,zeta01_z', real=True) zeta02_x, zeta02_y, zeta02_z = sm.symbols('zeta02_x,zeta02_y,zeta02_z', real=True) zeta03_x, zeta03_y, zeta03_z = sm.symbols('zeta03_x,zeta03_y,zeta03_z', real=True) # vectors Zeta00, Zeta01, Zeta02, Zeta03 = sm.symbols('Zeta00 Zeta01 Zeta02 Zeta03', real=True) Zeta00 = smarr.MutableDenseNDimArray([zeta00_x, zeta00_y, zeta00_z]) Zeta01 = smarr.MutableDenseNDimArray([zeta01_x, zeta01_y, zeta01_z]) Zeta02 = smarr.MutableDenseNDimArray([zeta02_x, zeta02_y, zeta02_z]) Zeta03 = smarr.MutableDenseNDimArray([zeta03_x, zeta03_y, zeta03_z]) ### external velocity at nodes - not required here # coordinates u00_x, u00_y, u00_z = sm.symbols('u00_x u00_y u00_z', real=True) u01_x, u01_y, u01_z = sm.symbols('u01_x u01_y u01_z', real=True) u02_x, u02_y, u02_z = sm.symbols('u02_x u02_y u02_z', real=True) u03_x, u03_y, u03_z = sm.symbols('u03_x u03_y u03_z', real=True) # vectors U00, U01, U02, U03 = sm.symbols('U00 U01 U02 U03', real=True) U01 = smarr.MutableDenseNDimArray([u00_x, u00_y, u00_z]) U02 = smarr.MutableDenseNDimArray([u01_x, u01_y, u01_z]) U03 = smarr.MutableDenseNDimArray([u02_x, u02_y, u02_z])
Scalar quantities are all lower case, e.g. zeta Arrays begin with upper case, e.g. Zeta_i 2 D Matrices are all upper case, e.g. AW, ZETA=[Zeta_i] 3 D arrays (tensors) will be labelled with a 3 in the name, e.g. A3 ''' import numpy as np import sympy as sm import sympy.tensor.array as smarr import linfunc ### Position vectors of vortex element Zeta01, Zeta02 = sm.symbols('Zeta01 Zeta02', real=True) zeta01_x,zeta02_x,zeta01_y,zeta02_y=\ sm.symbols('zeta01_x,zeta02_x,zeta01_y,zeta02_y', real=True) Zeta01 = smarr.MutableDenseNDimArray([zeta01_x, zeta01_y]) Zeta02 = smarr.MutableDenseNDimArray([zeta02_x, zeta02_y]) ### Segment point ZetaCA, ZetaCB = sm.symbols('ZetaCA,ZetaCB', real=True) zetaCA_x, zetaCA_y, zetaCB_x, zetaCB_y = sm.symbols( 'zetaCA_x,zetaCA_y,zetaCB_x,zetaCB_y', real=True) ZetaCA = smarr.MutableDenseNDimArray([zetaCA_x, zetaCA_y]) ZetaCB = smarr.MutableDenseNDimArray([zetaCB_x, zetaCB_y]) ### Other symbles/constants Kskew2D = smarr.MutableDenseNDimArray([[0, -1], [1, 0]]) CF, Gamma, gamma_s = sm.symbols('CF Gamma gamma_s', real=True) # define order of derivation ZetaAllList = [
Sign convention: Scalar quantities are all lower case, e.g. zeta Arrays begin with upper case, e.g. Zeta_i 2 D Matrices are all upper case, e.g. AW, ZETA=[Zeta_i] 3 D arrays (tensors) will be labelled with a 3 in the name, e.g. A3 ''' import numpy as np import sympy as sm import sympy.tensor.array as smarr import linfunc ### Position vectors of vortex element Zeta01 = sm.symbols('Zeta01', real=True) zeta01_x, zeta01_y = sm.symbols('zeta01_x,zeta01_y', real=True) Zeta01 = smarr.MutableDenseNDimArray([zeta01_x, zeta01_y]) ### Segment point ZetaC = sm.symbols('ZetaC', real=True) zetaC_x, zetaC_y = sm.symbols('zetaC_x,zetaC_y', real=True) ZetaC = smarr.MutableDenseNDimArray([zetaC_x, zetaC_y]) ### Other symbles/constants Kskew2D = smarr.MutableDenseNDimArray([[0, -1], [1, 0]]) CF, gamma01, gammaC = sm.symbols('CF gamma01 gammaC', real=True) # define order of derivation ZetaAllList = [ zeta01_x, zeta01_y, # w.r.t. segment 01 zetaC_x,
''' import sympy as sm import sympy.tensor.array as smarr 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