Exemple #1
0
def eval_seg_comp_loop(DerP, DerA, DerB, ZetaP, ZetaA, ZetaB, gamma_seg):
    '''
	Derivative of induced velocity Q w.r.t. collocation and segment coordinates 
	in format:
		[ (x,y,z) of Q, (x,y,z) of Zeta ]
	Warning: function optimised for performance. Variables are scaled during the
	execution.
	'''

    Cfact = cfact_biot * gamma_seg

    RA = ZetaP - ZetaA
    RB = ZetaP - ZetaB
    RAB = ZetaB - ZetaA
    Vcr = libalg.cross3d(RA, RB)
    vcr2 = np.dot(Vcr, Vcr)

    # numerical radious
    if vcr2 < (VORTEX_RADIUS_SQ * libalg.normsq3d(RAB)):
        return

    ### other constants
    ra1, rb1 = libalg.norm3d(RA), libalg.norm3d(RB)
    rainv = 1. / ra1
    rbinv = 1. / rb1
    Tv = RA * rainv - RB * rbinv
    dotprod = np.dot(RAB, Tv)

    ### --------------------------------------------- cross-product derivatives
    # lower triangular part only
    vcr2inv = 1. / vcr2
    vcr4inv = vcr2inv * vcr2inv
    diag_fact = Cfact * vcr2inv * dotprod
    off_fact = -2. * Cfact * vcr4inv * dotprod
    Dvcross = [[diag_fact + off_fact * Vcr[0]**2],
               [off_fact * Vcr[0] * Vcr[1], diag_fact + off_fact * Vcr[1]**2],
               [
                   off_fact * Vcr[0] * Vcr[2], off_fact * Vcr[1] * Vcr[2],
                   diag_fact + off_fact * Vcr[2]**2
               ]]

    ### ------------------------------------------ difference terms derivatives
    Vsc = Vcr * vcr2inv * Cfact
    Ddiff = np.array([RAB * Vsc[0], RAB * Vsc[1], RAB * Vsc[2]])
    dQ_dRAB = np.array([Tv * Vsc[0], Tv * Vsc[1], Tv * Vsc[2]])

    ### ---------------------------------------------- Final assembly (crucial)
    # ps: calling Dvcross_by_skew3d does not slow down execution.

    dQ_dRA=Dvcross_by_skew3d(Dvcross,-RB)\
           +np.dot(Ddiff, der_runit(RA,rainv,-rainv**3))
    dQ_dRB=Dvcross_by_skew3d(Dvcross, RA)\
           -np.dot(Ddiff, der_runit(RB,rbinv,-rbinv**3))

    DerP += dQ_dRA + dQ_dRB  # w.r.t. P
    DerA -= dQ_dRAB + dQ_dRA  # w.r.t. A
    DerB += dQ_dRAB - dQ_dRB  # w.r.t. B
Exemple #2
0
def biot_segment(zetaP,zetaA,zetaB,gamma=1.0):
	'''
	Induced velocity of segment A_>B of circulation gamma over point P.
	'''

	# differences
	ra=zetaP-zetaA
	rb=zetaP-zetaB
	rab=zetaB-zetaA
	ra_norm,rb_norm=libalg.norm3d(ra),libalg.norm3d(rb)
	vcross=libalg.cross3d(ra,rb)
	vcross_sq=np.dot(vcross,vcross)

	# numerical radious
	if vcross_sq<(VORTEX_RADIUS_SQ*libalg.normsq3d(rab)):
		return np.zeros((3,))

	q=((cfact_biot*gamma/vcross_sq)*\
		( np.dot(rab,ra)/ra_norm - np.dot(rab,rb)/rb_norm)) * vcross

	return q
Exemple #3
0
def biot_panel_fast(zetaC,ZetaPanel,gamma=1.0):
	'''
	Induced velocity over point ZetaC of a panel of vertices coordinates 
	ZetaPanel and circulaiton gamma, where:
		ZetaPanel.shape=(4,3)=[vertex local number, (x,y,z) component]
	'''

	Cfact=cfact_biot*gamma
	q=np.zeros((3,))

	R_list = zetaC-ZetaPanel
	Runit_list=[R_list[ii]/libalg.norm3d(R_list[ii]) for ii in svec]

	for aa,bb in LoopPanel:

		RAB=ZetaPanel[bb,:]-ZetaPanel[aa,:]	# segment vector
		Vcr = libalg.cross3d(R_list[aa],R_list[bb])
		vcr2=np.dot(Vcr,Vcr)
		if vcr2<(VORTEX_RADIUS_SQ*libalg.normsq3d(RAB)):
			continue

		q+=( (Cfact/vcr2)*np.dot(RAB,Runit_list[aa]-Runit_list[bb]) ) *Vcr

	return q
Exemple #4
0
def eval_panel_fast_coll(zetaP, ZetaPanel, gamma_pan=1.0):
    '''
	Computes derivatives of induced velocity w.r.t. coordinates of target point,
	zetaP, coordinates. Returns two elements:
		- DerP: derivative of induced velocity w.r.t. ZetaP, with:
			DerP.shape=(3,3) : DerC[ Uind_{x,y,z}, ZetaC_{x,y,z} ]

	The function is based on eval_panel_fast, but does not perform operations
	required to compute the derivatives w.r.t. the panel coordinates.
	'''

    DerP = np.zeros((3, 3))

    ### ---------------------------------------------- Compute common variables
    # these are constants or variables depending only on vertices and P coords
    Cfact = cfact_biot * gamma_pan

    # distance vertex ii-th from P
    R_list = zetaP - ZetaPanel
    r1_list = [libalg.norm3d(R_list[ii]) for ii in svec]
    r1inv_list = [1. / r1_list[ii] for ii in svec]
    Runit_list = [R_list[ii] * r1inv_list[ii] for ii in svec]
    Der_runit_list = [
        der_runit(R_list[ii], r1inv_list[ii], -r1inv_list[ii]**3)
        for ii in svec
    ]

    ### ------------------------------------------------- Loop through segments
    for aa, bb in LoopPanel:

        RAB = ZetaPanel[bb, :] - ZetaPanel[aa, :]  # segment vector
        Vcr = libalg.cross3d(R_list[aa], R_list[bb])
        vcr2 = np.dot(Vcr, Vcr)

        if vcr2 < (VORTEX_RADIUS_SQ * libalg.normsq3d(RAB)):
            continue

        Tv = Runit_list[aa] - Runit_list[bb]
        dotprod = np.dot(RAB, Tv)

        ### ----------------------------------------- cross-product derivatives
        # lower triangular part only
        vcr2inv = 1. / vcr2
        vcr4inv = vcr2inv * vcr2inv
        diag_fact = Cfact * vcr2inv * dotprod
        off_fact = -2. * Cfact * vcr4inv * dotprod
        Dvcross = [[diag_fact + off_fact * Vcr[0]**2],
                   [
                       off_fact * Vcr[0] * Vcr[1],
                       diag_fact + off_fact * Vcr[1]**2
                   ],
                   [
                       off_fact * Vcr[0] * Vcr[2], off_fact * Vcr[1] * Vcr[2],
                       diag_fact + off_fact * Vcr[2]**2
                   ]]

        ### ---------------------------------------- difference term derivative
        Vsc = Vcr * vcr2inv * Cfact
        Ddiff = np.array([RAB * Vsc[0], RAB * Vsc[1], RAB * Vsc[2]])

        ### ------------------------------------------ Final assembly (crucial)

        # dQ_dRA=Dvcross_by_skew3d(Dvcross,-R_list[bb])\
        # 									 +np.dot(Ddiff, Der_runit_list[aa] )
        # dQ_dRB=Dvcross_by_skew3d(Dvcross, R_list[aa])\
        # 									 -np.dot(Ddiff, Der_runit_list[bb] )

        DerP += Dvcross_by_skew3d(Dvcross,RAB)+\
             +np.dot(Ddiff, Der_runit_list[aa]-Der_runit_list[bb] )

    return DerP
Exemple #5
0
def eval_panel_fast(zetaP, ZetaPanel, gamma_pan=1.0):
    '''
	Computes derivatives of induced velocity w.r.t. coordinates of target point,
	zetaP, and panel coordinates. Returns two elements:
		- DerP: derivative of induced velocity w.r.t. ZetaP, with:
			DerP.shape=(3,3) : DerC[ Uind_{x,y,z}, ZetaC_{x,y,z} ]
		- DerVertices: derivative of induced velocity wrt panel vertices, with:
			DerVertices.shape=(4,3,3) : 
			DerVertices[ vertex number {0,1,2,3},  Uind_{x,y,z}, ZetaC_{x,y,z} ]

	The function is based on eval_panel_comp, but minimises operationsby 
	recycling variables.
	'''

    DerP = np.zeros((3, 3))
    DerVertices = np.zeros((4, 3, 3))

    ### ---------------------------------------------- Compute common variables
    # these are constants or variables depending only on vertices and P coords
    Cfact = cfact_biot * gamma_pan

    # distance vertex ii-th from P
    R_list = zetaP - ZetaPanel
    r1_list = [libalg.norm3d(R_list[ii]) for ii in svec]
    r1inv_list = [1. / r1_list[ii] for ii in svec]
    Runit_list = [R_list[ii] * r1inv_list[ii] for ii in svec]
    Der_runit_list = [
        der_runit(R_list[ii], r1inv_list[ii], -r1inv_list[ii]**3)
        for ii in svec
    ]

    ### ------------------------------------------------- Loop through segments
    for aa, bb in LoopPanel:

        RAB = ZetaPanel[bb, :] - ZetaPanel[aa, :]  # segment vector
        Vcr = libalg.cross3d(R_list[aa], R_list[bb])
        vcr2 = np.dot(Vcr, Vcr)

        if vcr2 < (VORTEX_RADIUS_SQ * libalg.normsq3d(RAB)):
            continue

        Tv = Runit_list[aa] - Runit_list[bb]
        dotprod = np.dot(RAB, Tv)

        ### ----------------------------------------- cross-product derivatives
        # lower triangular part only
        vcr2inv = 1. / vcr2
        vcr4inv = vcr2inv * vcr2inv
        diag_fact = Cfact * vcr2inv * dotprod
        off_fact = -2. * Cfact * vcr4inv * dotprod
        Dvcross = [[diag_fact + off_fact * Vcr[0]**2],
                   [
                       off_fact * Vcr[0] * Vcr[1],
                       diag_fact + off_fact * Vcr[1]**2
                   ],
                   [
                       off_fact * Vcr[0] * Vcr[2], off_fact * Vcr[1] * Vcr[2],
                       diag_fact + off_fact * Vcr[2]**2
                   ]]

        ### ---------------------------------------- difference term derivative
        Vsc = Vcr * vcr2inv * Cfact
        Ddiff = np.array([RAB * Vsc[0], RAB * Vsc[1], RAB * Vsc[2]])

        ### ---------------------------------------------------- RAB derivative
        dQ_dRAB = np.array([Tv * Vsc[0], Tv * Vsc[1], Tv * Vsc[2]])

        ### ------------------------------------------ Final assembly (crucial)

        dQ_dRA=Dvcross_by_skew3d(Dvcross,-R_list[bb])\
                  +np.dot(Ddiff, Der_runit_list[aa] )
        dQ_dRB=Dvcross_by_skew3d(Dvcross, R_list[aa])\
                  -np.dot(Ddiff, Der_runit_list[bb] )

        DerP += dQ_dRA + dQ_dRB  # w.r.t. P
        DerVertices[aa, :, :] -= dQ_dRAB + dQ_dRA  # w.r.t. A
        DerVertices[bb, :, :] += dQ_dRAB - dQ_dRB  # w.r.t. B

        # ### collocation point only
        # DerP +=Dvcross_by_skew3d(Dvcross,RA-RB)+np.dot(Ddiff,
        # 		  der_runit(RA,rainv,minus_rainv3)-der_runit(RB,rbinv,minus_rbinv3))

    return DerP, DerVertices