示例#1
0
def FastForce(X, Y, Xss, Yss, LinkIndices, LinkData, LinkCurL, TetherIndex,
              TetherData):
    Nb = len(X)

    tx = X[LinkIndices[:, 1]] - X[LinkIndices[:, 0]]
    ty = Y[LinkIndices[:, 1]] - Y[LinkIndices[:, 0]]

    LinkCurL[:] = (tx**2 + ty**2)**.5

    txl = tx / LinkCurL
    tyl = ty / LinkCurL

    for i in range(Nb):
        if LinkCurL[i] == 0:
            txl[i] = tyl[i] = 0.

    Xss[:], Yss[:] = 0. * Xss, 0. * Yss
    calc = LinkData[:, 0] * (tx - LinkData[:, 1] * txl)
    IB_c.CollapseSum(Xss, LinkIndices[:, 0], calc)
    IB_c.CollapseSum(Xss, LinkIndices[:, 1], -calc)

    calc = LinkData[:, 0] * (ty - LinkData[:, 1] * tyl)
    IB_c.CollapseSum(Yss, LinkIndices[:, 0], calc)
    IB_c.CollapseSum(Yss, LinkIndices[:, 1], -calc)

    Xss[TetherIndex] += TetherData[:, 0] * (TetherData[:, 1] - X[TetherIndex])
    Yss[TetherIndex] += TetherData[:, 0] * (TetherData[:, 2] - Y[TetherIndex])
def CalculateLookupTable_3D(fluid, spread=True, Range=10000):
    U = zeros((fluid.N[0], fluid.N[1], fluid.N[2], 3, 3), float64)
    X = zeros((1, 3), float64)

    F = X.copy()

    # Calculate the lookup table for a unit force in the x direction
    F[0] = [1, 0, 0]

    FiberToGrid(fluid.N, fluid.h, 1, 1., X, F, fluid.f, fluid.DeltaType)
    fluid.FluidSolve(fluid.f)

    if (spread):
        IB_c.WholeGridSpread(fluid.Output_u, fluid.N, fluid.h, U[..., 0, :],
                             Range, fluid.DeltaType)
    else:
        U[..., 0, :] = fluid.Output_u.copy()

    # If the domain is perfectly cubic make use of symmetries
    if fluid.N[0] == fluid.N[1] == fluid.N[2]:
        U[..., 1, :] = U[..., 0, :].swapaxes(0, 1)
        U[..., 1, 0], U[..., 1, 1] = U[..., 1, 1].copy(), U[..., 1, 0].copy()
        U[..., 2, :] = U[..., 0, :].swapaxes(0, 2)
        U[..., 2, 0], U[..., 2, 2] = U[..., 2, 2].copy(), U[..., 2, 0].copy()
    # otherwise calculate y and z components from scratch
    else:
        # Calculate the lookup table for a unit force in the y direction
        F[0] = [0, 1, 0]

        FiberToGrid(fluid.N, fluid.h, 1, 1., X, F, fluid.f, fluid.DeltaType)
        fluid.FluidSolve(fluid.f)

        if (spread):
            IB_c.WholeGridSpread(fluid.Output_u, fluid.N, fluid.h,
                                 U[..., 1, :], Range, fluid.DeltaType)
        else:
            U[..., 1, :] = fluid.Output_u.copy()

        # Calculate the lookup table for a unit force in the z direction
        F[0] = [0, 0, 1]

        FiberToGrid(fluid.N, fluid.h, 1, 1., X, F, fluid.f, fluid.DeltaType)
        fluid.FluidSolve(fluid.f)

        if (spread):
            IB_c.WholeGridSpread(fluid.Output_u, fluid.N, fluid.h,
                                 U[..., 2, :], Range, fluid.DeltaType)
        else:
            U[..., 2:] = fluid.Output_u.copy()

    return U
示例#3
0
def GridToFiber_3D(N, h, Nb, hb, X, u, U, DeltaType=0, UseNativePython=False):
    """Interpolate a vector-field u to the points in X.
	
	The result is stored in U."""

    U *= 0

    if UseNativePython:
        # Loop through fiber points
        for i in range(Nb):
            # Modify velocity for nearby points
            jMin = int(X[i][0] / h[0] - 2.)
            jMax = jMin + 5
            kMin = int(X[i][1] / h[1] - 2.)
            kMax = kMin + 5
            lMin = int(X[i][2] / h[2] - 2.)
            lMax = lMin + 5

            for j in range(jMin, jMax + 1):
                __delt = Delta(h[0], j * h[0] - X[i][0],
                               DeltaType) * h[0] * h[1] * h[2]
                for k in range(kMin, kMax + 1):
                    _delt = __delt * Delta(h[1], k * h[1] - X[i][1], DeltaType)
                    for l in range(lMin, lMax + 1):
                        delt = _delt * Delta(h[2], l * h[2] - X[i][2],
                                             DeltaType)
                        U[i] += u[j % N[0], k % N[1], l % N[2]] * delt
    else:
        IB_c.GridToFiber(N, h, Nb, hb, X, u, U, DeltaType)

    return U
示例#4
0
def FiberToGrid_3D(N, h, Nb, hb, X, F, f, DeltaType=0, UseNativePython=False):
    """Spread a distribution F on X to the Eulerian grid f."""

    f *= 0

    if UseNativePython:
        # Loop through fiber points
        for i in range(Nb):
            # Modify force for nearby points
            jMin = int(X[i][0] / h[0] - 2.)
            jMax = jMin + 5
            kMin = int(X[i][1] / h[1] - 2.)
            kMax = kMin + 5
            lMin = int(X[i][2] / h[2] - 2.)
            lMax = lMin + 5

            for j in range(jMin, jMax + 1):
                __delt = Delta(h[0], j * h[0] - X[i][0], DeltaType) * hb
                for k in range(kMin, kMax + 1):
                    _delt = __delt * Delta(h[1], k * h[1] - X[i][1], DeltaType)
                    for l in range(lMin, lMax + 1):
                        delt = _delt * Delta(h[2], l * h[2] - X[i][2],
                                             DeltaType)
                        f[j % N[0], k % N[1], l % N[2]] += F[i] * delt
    else:
        IB_c.FiberToGrid(N, h, Nb, hb, X, F, f, DeltaType)

    return f
示例#5
0
def FastJacobian2(z, D, args, LinkIndices, LinkData, LinkCurL, TetherIndex,
                  TetherData):
    tx = z[LinkIndices[:, 1]] - z[LinkIndices[:, 0]]
    ty = z[LinkIndices[:, 1] + Nb] - z[LinkIndices[:, 0] + Nb]

    l3 = LinkCurL**3
    l1 = 1. / LinkCurL

    dxdx = (-1. + LinkData[:, 1] * (l1 - tx**2 / l3))
    dydy = (-1. + LinkData[:, 1] * (l1 - ty**2 / l3))
    dxdy = -LinkData[:, 1] * tx * ty / l3

    for i in range(Nb):
        if LinkCurL[i] == 0:
            dxdx[i] = -1.
            dydy[i] = -1.
            dxdy[i] = 0.
        print i, LinkCurL[i], dxdx[i], dxdy[i], dydy[i]

    data = 0. * D.data
    n = len(dxdx)

    data[:n] -= dxdx
    data[n:2 * n] -= dxdx

    data[2 * n:3 * n] -= dydy
    data[3 * n:4 * n] -= dydy

    data[4 * n:5 * n] -= dxdy
    data[5 * n:6 * n] -= dxdy

    data[6 * n:7 * n] -= dxdy
    data[7 * n:8 * n] -= dxdy

    Diag = zeros(Nb, float64)
    IB_c.CollapseSum(Diag, LinkIndices[:, 0], dxdx)
    IB_c.CollapseSum(Diag, LinkIndices[:, 1], dxdx)
    Diag[TetherIndex] -= 1.  #TetherData[:,0]
    data[8 * n:8 * n + Nb] = 1. * Diag

    Diag = zeros(Nb, float64)
    IB_c.CollapseSum(Diag, LinkIndices[:, 0], dydy)
    IB_c.CollapseSum(Diag, LinkIndices[:, 1], dydy)
    Diag[TetherIndex] -= 1.  #TetherData[:,0]
    data[8 * n + Nb:8 * n + 2 * Nb] = 1. * Diag

    Diag = zeros(Nb, float64)
    IB_c.CollapseSum(Diag, LinkIndices[:, 0], dxdy)
    IB_c.CollapseSum(Diag, LinkIndices[:, 1], dxdy)
    data[8 * n + 2 * Nb:8 * n + 3 * Nb] = 1. * Diag

    Diag = zeros(Nb, float64)
    IB_c.CollapseSum(Diag, LinkIndices[:, 1], dxdy)
    IB_c.CollapseSum(Diag, LinkIndices[:, 0], dxdy)
    data[8 * n + 3 * Nb:8 * n + 4 * Nb] = 1. * Diag

    D.data[args] = data
def EzSparse(N, M, A):
    IShell = zeros((N, 3), float64)
    IShelli = zeros((N, 3), int32)
    IShelld = zeros(N, int32)

    IB_c.EzSparse(N, M, A, IShell, IShelli, IShelld)

    return (N, M, max(list(IShelld)), IShell, IShelli, IShelld)
def ModVCycle(A, P, L, b, I, x, damp=.3):
    if len(I) <= 1:
        return

#    GaussSeidel(len(x), A[0], b, x)
    IB_c.GaussSeidel(len(x), A[0], b, x, damp)
    #    Jacobi(A[0], b, x)

    r = b - dot(A[0], x)
    x[L] += linalg.solve(P, r[L])

    r = I[0].T * (b - dot(A[0], x))
    _x = zeros(len(r), float64)
    FastVCycle(A[1:], r, I[1:], _x)
    x += I[0] * _x

    #    GaussSeidel(len(x), A[0], b, x)
    IB_c.GaussSeidel(len(x), A[0], b, x, damp)
	def ConstructFluidMatrix(self, fluid, M=None):
		if M == None:
			# Allocate memory to store the matrix
			Dim = fluid.Dim
			M = zeros((Dim * self.Nb, Dim * self.Nb), float64)
		else:
			M *= 0
			
		# Construct the matrix
		IB_c.ComputeMatrix(self.X, fluid.N, self.Nb, fluid.h, self.hb, fluid.GetLookup(), M, 100000)
	
		return M
def FastVCycle(A, b, I, x, damp=.3):
    if len(I) <= 1:
        return

    #Jacobi(A[0], b, x)
    #GaussSeidel(len(x), A[0], b, x)
    IB_c.GaussSeidel(len(x), A[0], b, x, damp)

    r = I[0].T * (b - dot(A[0], x))
    _x = zeros(len(r), float64)
    FastVCycle(A[1:], r, I[1:], _x)
    x += I[0] * _x
示例#10
0
def FluidSolve(u, v, ux, vx, uy, vy, X, Y, Fx, Fy):
    IB_c.CentralDerivative_x(N, M, h, u, ux)
    IB_c.CentralDerivative_x(N, M, h, v, vx)
    IB_c.CentralDerivative_y(N, M, h, u, uy)
    IB_c.CentralDerivative_y(N, M, h, v, vy)

    fx, fy = ForceToGrid(N, M, h, Nb, hb, Old_X, Old_Y, Fx, Fy)

    fx, fy = ExplicitTerms(dt, u, v, ux, uy, vx, vy, fx, fy)

    fx = fft2(fx)
    fy = fft2(fy)

    P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
    P[0, 0] = 0.

    u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy)

    u = ifft2(u).real
    v = ifft2(v).real

    return VelToFiber(N, M, h, Nb, hb, 1., X, Y, u, v)
示例#11
0
def EzSparseMM(A1, A2, newB=True, B=-1):
    N, M, s, IShell, IShelli, IShelld = A1

    _N, _M = A2.shape

    if M != _N:
        raise ("Incompatible dimensions")

    if newB:
        B = zeros((N, _M), float64)

    IB_c.SparseMM(N, M, _M, s, IShell, IShelli, IShelld, A2, B)

    return B
def CalculateLookupTable2(fluid, M=4, spread=True, Range=10000, offset=0):
    """Calculates a lookup table for the interpolated velocity generated by a point force
	The table has dimensions 3xN[0]xN[1]xN[2]x3, where the first dimension specifies the direction of the force"""

    if Range > fluid.N[0]:
        Range = fluid.N[0] / 2 + 1
    U = zeros((M + 1, M + 1, M + 1, 3, Range, Range, Range, 3), float64)

    X = zeros((1, 3), float64)
    F = X.copy()

    for j in range(M + 1):
        for k in range(M + 1):
            for l in range(M + 1):
                X[0] = 1. / M * array([j, k, l]) * fluid.h
                X[0] += array([1, 1, 1]) * fluid.h * offset
                print j, k, l, X[0] / fluid.h, array([1, 1, 1]) * fluid.h

                F[0] = [1, 0, 0]
                FiberToGrid(fluid.N, fluid.h, 1, 1., X, F, fluid.f,
                            fluid.DeltaType)
                fluid.FluidSolve(fluid.f)
                if (spread):
                    IB_c.WholeGridSpread2(fluid.Output_u, fluid.N, fluid.h,
                                          U[j, k, l,
                                            0], Range, fluid.DeltaType)
                    raise ValueError("WholeGridSpread2 not yet implemented")
                else:
                    U[j, k, l,
                      0] = fluid.Output_u[:Range, :Range, :Range].copy()

                if fluid.N[0] == fluid.N[1] == fluid.N[2]:
                    U[j, k, l, 1] = U[j, k, l, 0].swapaxes(0, 1)
                    U[j, k, l, 1, :, :, :,
                      0], U[j, k, l, 1, :, :, :,
                            1] = U[j, k, l, 1, :, :, :,
                                   1].copy(), U[j, k, l, 1, :, :, :, 0].copy()
                    U[j, k, l, 2] = U[j, k, l, 0].swapaxes(0, 2)
                    U[j, k, l, 2, :, :, :,
                      0], U[j, k, l, 2, :, :, :,
                            2] = U[j, k, l, 2, :, :, :,
                                   2].copy(), U[j, k, l, 2, :, :, :, 0].copy()
                else:
                    raise ValueError(
                        "CalculateLookupTable2 not implemented for non-cube domains."
                    )

    return U
def ForceToGrid(N, M, h, Nb, hb, X, Y, Boundary_fx, Boundary_fy, DeltaType=0):
    fx = zeros((N, M), float64)
    fy = zeros((N, M), float64)

    ##    # Loop through fiber points
    ##    for i in range(Nb):
    ##        # Modify force for nearby points
    ##        jMin = int(X[i] / h - 2.)
    ##        jMax = jMin + 5
    ##        kMin = int(Y[i] / h - 2.)
    ##        kMax = kMin + 5
    ##
    ##        for j in range(jMin, jMax + 1):
    ##            deltx = Delta (h, j * h - X[i])
    ##            for k in range(kMin, kMax + 1):
    ##                delt = deltx * Delta (h, k * h - Y[i]) * hb
    ##                fx[j%N][k%M] = fx[j%N][k%M] + Boundary_fx[i] * delt
    ##                fy[j%N][k%M] = fy[j%N][k%M] + Boundary_fy[i] * delt

    IB_c.ForceToGrid(N, M, h, Nb, hb, X, Y, Boundary_fx, Boundary_fy, fx, fy,
                     DeltaType)

    return fx, fy
def VelToFiber(N, M, h, Nb, hb, dt, X, Y, u, v, DeltaType=0):
    ##    Xvel = zeros(Nb, float64)
    ##    Yvel = zeros(Nb, float64)
    ##
    ##    # Loop through fiber points
    ##    for i in range(Nb):
    ##        # Modify velocity for nearby points
    ##        jMin = int(X[i] / h - 2.)
    ##        jMax = jMin + 5
    ##        kMin = int(Y[i] / h - 2.)
    ##        kMax = kMin + 5
    ##
    ##        for j in range(jMin, jMax + 1):
    ##            deltx = Delta (h, j * h - X[i])
    ##            for k in range(kMin, kMax + 1):
    ##                delt = deltx * Delta (h, k * h - Y[i]) * h**2
    ##                Xvel[i] += u[j%N][k%M] * delt
    ##                Yvel[i] += v[j%N][k%M] * delt

    Xvel = zeros(Nb, float64)
    Yvel = zeros(Nb, float64)
    IB_c.VelToFiber(N, M, h, Nb, hb, dt, X, Y, u, v, Xvel, Yvel, DeltaType)

    return dt * Xvel, dt * Yvel
Domain_x, Domain_y = 2., 1.
#h = .003
h = Domain_x / 100.
N, M = int(Domain_x / h), int(Domain_y / h)
Domain_x, Domain_y = N * h, M * h
print "N, M =", N, M
dt = .003
T = 5.
CurT = 0

_s = 5000000000.
Current = 100.

WideLambda = zeros((N, M), float64)
ShortLambda = zeros((N, M), float64)
IB_c.InitWideLaplacian(N, M, h, WideLambda)
IB_c.InitShortLaplacian(N, M, h, ShortLambda)
DxSymbol = InitDxSymbol(N, M, h)
DySymbol = InitDySymbol(N, M, h)

_h = h
_N, _M = int(Domain_x / _h), int(Domain_y / _h)
UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt)

print UField[0, 0], VField2[0, 0]
clf()
clf()
imshow(UField)
colorbar()
#show(); #&&raw_input("")
clf()
def ExplicitHeartValveSim(N, dx, dt, T):
    Domain_x, Domain_y = 2., 1.
    #h = .003#.007
    h = Domain_x / N
    dx = h / 2.
    N, M = int(Domain_x / h), int(Domain_y / h)
    #dt = .0000065
    CurT = 0

    _s = 1000000000. / dx**2
    #_s = 500000000000. / dx**2
    dt = 30. * h / _s**.5
    Current = 100.

    WideLambda = zeros((N, M), float64)
    ShortLambda = zeros((N, M), float64)
    IB_c.InitWideLaplacian(N, M, h, WideLambda)
    IB_c.InitShortLaplacian(N, M, h, ShortLambda)
    DxSymbol = InitDxSymbol(N, M, h)
    DySymbol = InitDySymbol(N, M, h)

    #UField, VField = InitVelField(N, M, h, h, dt)

    X, Y, Links, Tethers, Parts = ConstructValve(_s, 0., Domain_x, 0.,
                                                 Domain_y, dx, False, 1.3,
                                                 1.1)  #.01)
    #X, Y, Links, Tethers, Parts = ConstructValve (_s, 0., Domain_x, 0., Domain_y, .012, True,1.5,1.)#.01)
    #X, Y, Links, Tethers, Valve = ConstructValve (_s, 0., 2., 0., 1., .03)#.01)
    Links = []
    Nb = len(X)
    hb = 1. / Nb
    ##for j in range(Nb):
    ##    X[j] += .002*cos(j)
    ##    Y[j] += .002*sin(j**2)

    Xs = zeros(Nb, float64)
    Ys = zeros(Nb, float64)
    Xss = zeros(Nb, float64)
    Yss = zeros(Nb, float64)
    u = zeros((N, M), float64)
    v = zeros((N, M), float64)
    ux = zeros((N, M), float64)
    vx = zeros((N, M), float64)
    uy = zeros((N, M), float64)
    vy = zeros((N, M), float64)
    fx = zeros((N, M), float64)
    fy = zeros((N, M), float64)

    # Unpack link and tether data into arrays
    LinkIndices = zeros((len(Links), 2), int64)
    LinkData = zeros((len(Links), 2), float64)
    LinkCurL = zeros(len(Links), float64)
    TetherData = zeros((len(Tethers), 3), float64)
    TetherIndex = zeros(len(Tethers), int64)
    for l in range(len(Links)):
        a, b, s, L = Links[l]
        LinkIndices[l, :] = [a, b]
        LinkData[l, :] = [s, L]
    for l in range(len(Tethers)):
        a, x, s = Tethers[l]
        x, y = x
        TetherData[l, :] = [s, x, y]
        TetherIndex[l] = a

    PlotValve(X, Y, Links)

    Times = []
    A = zeros((2 * Nb, 2 * Nb), float64)

    print N, dx, Nb, dt

    b = zeros(2 * Nb, float64)
    count = 0
    TotalTime = 0
    print
    print "Time:",
    while CurT < T:
        Old_X, Old_Y = 1. * X, 1. * Y
        #        print "Time:", CurT, count
        #        print CurT,
        #        CurT += dt

        Time = time.time()

        IB_c.CentralDerivative_x(N, M, h, u, ux)
        IB_c.CentralDerivative_x(N, M, h, v, vx)
        IB_c.CentralDerivative_y(N, M, h, u, uy)
        IB_c.CentralDerivative_y(N, M, h, v, vy)

        FastForce(X, Y, Xss, Yss, LinkIndices, LinkData, LinkCurL, TetherIndex,
                  TetherData)
        #        Xss, Yss = FiberForce (Nb, X, Y, Xss, Yss, Links, Tethers)
        fx, fy = ForceToGrid(N, M, h, Nb, hb, X, Y, Xss, Yss)

        fx, fy = ExplicitTerms(dt, u, v, ux, uy, vx, vy, fx, fy)
        fx += dt * Current * ones((N, M), float64)

        fx = fft2(fx)
        fy = fft2(fy)

        P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
        P[0, 0] = 0.

        u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy)

        u = ifft2(u).real
        v = ifft2(v).real

        Xvel, Yvel = VelToFiber(N, M, h, Nb, hb, 1., X, Y, u, v)
        X, Y = X + dt * Xvel, Y + dt * Yvel

        #        print "Explicit time:", time.time() - Time
        #        Times.append(time.time() - Time)
        #        print "avg:", sum(Times)/len(Times)

        ##        if time.time()-Time > 1:
        ##            P = ifft2(P).real
        ##            clf()
        ##            imshow(P)
        ##            scatter(M*Y,N*X/2)
        ##            quiver(M*Y,N*X/2,Yvel,-Xvel)
        ##            print "Halt!"
        ##            raw_input("")

        Time = time.time() - Time
        TotalTime += Time
        count += 1

        Ts = [.0001, .0002, .0005, .001, .005]
        for _T in Ts:
            if CurT < _T and CurT + dt >= _T:
                print "Time", _T, ":", count, TotalTime, TotalTime / count
        #print "Time:", CurT
        CurT += dt

        if count % 500 == 0:
            print CurT, count
            P = ifft2(P).real
            clf()
            #imshow(P)
            imshow(u)
            colorbar()

            scatter(M * Y, N * X / 2)
            quiver(M * Y, N * X / 2, Yvel, -Xvel)
    #        #_!_print gaussx[0:Nb]
    #        raw_input("")

    print
    print
    print "End:", count, TotalTime, TotalTime / count
    return Times
def Call(N):
    #    N = 128
    Domain_x, Domain_y = 2., 1.
    #h = .003#.007
    h = Domain_x / N
    dx = h / 2.
    N, M = int(Domain_x / h), int(Domain_y / h)
    #dt = .0000065
    CurT = 0
    T = .5

    #_s = 500000000000. / dx**2
    _s = 1000000000. / dx**2
    dt = .0025
    Current = 100.

    WideLambda = zeros((N, M), float64)
    ShortLambda = zeros((N, M), float64)
    IB_c.InitWideLaplacian(N, M, h, WideLambda)
    IB_c.InitShortLaplacian(N, M, h, ShortLambda)
    DxSymbol = InitDxSymbol(N, M, h)
    DySymbol = InitDySymbol(N, M, h)

    _h = h
    _N, _M = int(Domain_x / _h), int(Domain_y / _h)
    UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt)

    print UField[0, 0], VField2[0, 0]
    clf()
    clf()
    imshow(UField)
    colorbar()
    #show(); #&&raw_input("")
    clf()
    imshow(VField2)
    colorbar()
    #show(); #&&raw_input("")

    X, Y, Links, Tethers, Parts = ConstructValve(
        _s, 0., Domain_x, 0., Domain_y, dx,
        False)  #, 1., 1.15)#, True, 1.3,1.7)#.01)
    Nb = len(X)

    Xs = zeros(Nb, float64)
    Ys = zeros(Nb, float64)
    Xss = zeros(Nb, float64)
    Yss = zeros(Nb, float64)
    u = zeros((N, M), float64)
    v = zeros((N, M), float64)
    ux = zeros((N, M), float64)
    vx = zeros((N, M), float64)
    uy = zeros((N, M), float64)
    vy = zeros((N, M), float64)
    fx = zeros((N, M), float64)
    fy = zeros((N, M), float64)

    # Unpack link and tether data into arrays
    LinkIndices = zeros((len(Links), 2), int64)
    LinkData = zeros((len(Links), 2), float64)
    LinkCurL = zeros(len(Links), float64)
    TetherData = zeros((len(Tethers), 3), float64)
    TetherIndex = zeros(len(Tethers), int64)
    for l in range(len(Links)):
        a, b, s, L = Links[l]
        LinkIndices[l, :] = [a, b]
        LinkData[l, :] = [s, L]
    for l in range(len(Tethers)):
        a, x, s = Tethers[l]
        x, y = x
        TetherData[l, :] = [s, x, y]
        TetherIndex[l] = a

    DSeed = SeedJacobian(Nb, LinkIndices)
    SeedArgs = argsort(DSeed.data)

    __I, _x2, _y2, Parts2 = ReduceValve3(X, Y, Parts)
    #s2, __I, _x2, _y2, Links2, Tethers2, Parts2 = ReduceValve(_s, X, Y, Links, Tethers, Parts)
    Nb2 = len(_x2)

    _II = 1. * __I

    _n, _m = _II.shape
    __II = zeros((2 * _n, 2 * _m), float64)
    __II[:_n, :_m] = 1. * _II
    __II[_n:, _m:] = 1. * _II
    II = [sparse.csr_matrix(__II)]
    IIspT = [EzSparse(2 * _m, 2 * _n, __II.T)]
    _x3, _y3, Parts3 = _x2, _y2, Parts2
    #s3, _x3, _y3, Links3, Tethers3, Parts3 = s2, _x2, _y2, Links2, Tethers2, Parts2
    while len(_II) > 10 and len(II) < 7:
        holdlen = len(_II)
        print holdlen

        _II, _x3, _y3, Parts3 = ReduceValve3(_x3, _y3, Parts3)
        #s3, _II, _x3, _y3, Links3, Tethers3, Parts3 = ReduceValve(s3, _x3, _y3, Links3, Tethers3, Parts3)
        if len(_II) == holdlen:
            II = II[:len(II) - 2]
            break
        _n, _m = _II.shape
        __II = zeros((2 * _n, 2 * _m), float64)
        __II[:_n, :_m] = 1. * _II
        __II[_n:, _m:] = 1. * _II
        II.append(sparse.csr_matrix(__II))
        IIspT.append(EzSparse(2 * _m, 2 * _n, __II.T))

    print N, dt, _s
    print "Nb =", Nb
    hb = 1. / Nb
    hb = 1.

    PlotValve(X, Y, Links)

    i1, i2, i3 = Parts[3][0], Parts[3][0] + Nb, Parts[3][len(Parts[3]) - 1]
    Reduce = zeros((2 * Nb - 3, 2 * Nb), float64)
    j = 0
    for i in range(2 * Nb):
        if i != i1 and i != i2 and i != i3:
            Reduce[j, i] = 1.
            j += 1
    Reduce = sparse.csr_matrix(Reduce)

    l = []
    for i in range(Nb):
        if X[i] > .25 and X[i] < .4 and Y[i] < .49 and Y[i] > .31:
            l.extend([i, i + Nb])

    A = zeros((2 * Nb, 2 * Nb), float64)
    x = zeros(2 * Nb, float64)
    f = zeros(2 * Nb, float64)
    _f = zeros(2 * Nb, float64)
    _e1, _e2, _e3, F = 0 * x, 0 * x, 0 * x, 0 * x
    e1, e2, e3 = 0. * x, 0. * x, 0. * x

    for p in range(2, 7):
        for i in Parts[p]:
            e1[i] = 1.
            e2[i + Nb] = 1.

    Old_X, Old_Y = 1. * X, 1. * Y

    b = zeros(2 * Nb, float64)
    count = 0
    ShowStats = False
    TotalTime = 0
    TotalCount = 0
    MaxCurrent = 150.
    while CurT < T:
        ##    if CurT < .1:
        ##        Current = MaxCurrent * (CurT - 0.) * (.1 - CurT) / (.1 - .05)**2
        ##    else:
        ##        Current = -MaxCurrent * (CurT - .1) * (.2 - CurT) / (.1 - .05)**2
        ##    print "Current:", Current

        Time = time.time()

        Predict_X, Predict_Y = X + .5 * (X - Old_X), Y + .25 * (Y - Old_Y)

        Old_u, Old_v = 1. * u, 1. * v
        Old_X, Old_Y = 1. * X, 1. * Y

        IB_c.CentralDerivative_x(N, M, h, u, ux)
        IB_c.CentralDerivative_x(N, M, h, v, vx)
        IB_c.CentralDerivative_y(N, M, h, u, uy)
        IB_c.CentralDerivative_y(N, M, h, v, vy)

        fx, fy = ExplicitTerms(dt, u, v, ux, uy, vx, vy, 0., 0.)
        fx += dt * Current * ones((N, M), float64)

        fx = fft2(fx)
        fy = fft2(fy)

        P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
        P[0, 0] = 0.

        u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy)
        u = ifft2(u).real
        v = ifft2(v).real

        Xvel, Yvel = VelToFiber(N, M, h, Nb, hb, 1., X, Y, u, v)

        if ShowStats:
            print "Explicit:", time.time() - Time

        A = zeros((2 * Nb, 2 * Nb), float64)
        IB_c.ComputeMatrix(X, Y, _N, _M, Nb, _h, hb, UField, VField, UField2,
                           VField2, A, -1)  #N/6)

        if ShowStats:
            print "Compute A:", time.time() - Time

        __A = [dt * A]
        for i in range(len(II)):
            __A.append(EzSparseMM(IIspT[i], EzSparseMM(IIspT[i], __A[i].T).T))

        if ShowStats:
            print "Init Multi:", time.time() - Time

        P = dt * A[l, :][:, l]

        b[:Nb], b[Nb:] = X + dt * Xvel, Y + dt * Yvel
        x[0:Nb], x[Nb:2 * Nb] = 1. * X, 1. * Y

        ##    FastForce(x[:Nb], x[Nb:], f[:Nb], f[Nb:], LinkIndices, LinkData, LinkCurL, TetherIndex, TetherData)
        ##    xp = x + dt*dot(A,f)
        ##
        ##    for i in range(4):
        ##        x = x + e1 * dot(xp-x,e1)/dot(e1,e1) + e2 * dot(xp-x,e2)/dot(e2,e2)
        ##
        ##        center = e1*dot(x,e1)/dot(e1,e1) + e2*dot(x,e2)/dot(e2,e2)
        ##
        ##        z = x - center
        ##        e3 = 0. * x
        ##        for p in range(9,10):#range(2,7):
        ##            for i in Parts[p]:
        ##                e3[i] = z[i+Nb]
        ##                e3[i+Nb] = -z[i]
        ##        theta = dot(xp-x,e3)/dot(e3,e3)
        ##
        ##        Rot = zeros((2,2),float64)
        ##        Rot[0,0] = cos(theta)
        ##        Rot[1,0] = -sin(theta)
        ##        Rot[0,1] = -Rot[1,0]
        ##        Rot[1,1] = Rot[0,0]
        ##
        ##        for p in range(2,7):
        ##            for i in Parts[p]:
        ##                [z[i],z[i+Nb]] = dot(Rot, [z[i],z[i+Nb]])
        ##
        ##        x = z + center

        # Solve for rotational eigenvalue
        e3 = 0. * x
        z = x - e1 * dot(x, e1) / dot(e1, e1) - e2 * dot(x, e2) / dot(e2, e2)
        for p in range(2, 7):
            for i in Parts[p]:
                e3[i] = z[i + Nb]
                e3[i + Nb] = -z[i]

        _e1 = ModMultigridStep(__A, P, l, e1, II, _e1, 1.)
        _e2 = ModMultigridStep(__A, P, l, e2, II, _e2, 1.)
        _e3 = ModMultigridStep(__A, P, l, e3, II, _e3, 1.)

        ChangeX = 1.
        MaxRes = 1.
        count = 0
        F = 0. * F
        while MaxRes > .5 * dt and count < 4:
            holdx = 1. * x
            count += 1

            F = ModMultigridStep(__A, P, l, x - b, II, F, 1.)
            FastForce(x[:Nb], x[Nb:], _f[:Nb], _f[Nb:], LinkIndices, LinkData,
                      LinkCurL, TetherIndex, TetherData)
            f = F - _f

            # Solve for rotational eigenvalue
            e3 = 0. * x
            z = x - e1 * dot(x, e1) / dot(e1, e1) - e2 * dot(x, e2) / dot(
                e2, e2)
            for p in range(2, 7):
                for i in Parts[p]:
                    e3[i] = z[i + Nb]
                    e3[i + Nb] = -z[i]

            K = zeros((3, 3))
            K[0, 0] = dot(_e1, e1)
            K[0, 1] = dot(_e2, e1)
            K[0, 2] = dot(_e3, e1)
            K[1, 0] = dot(_e1, e2)
            K[1, 1] = dot(_e2, e2)
            K[1, 2] = dot(_e3, e2)
            K[2, 0] = dot(_e1, e3)
            K[2, 1] = dot(_e2, e3)
            K[2, 2] = dot(_e3, e3)

            _K = linalg.solve(K, array([dot(F, e1), dot(F, e2), dot(F, e3)]))
            x -= e1 * _K[0] + e2 * _K[1]

            center = e1 * dot(x, e1) / dot(e1, e1) + e2 * dot(x, e2) / dot(
                e2, e2)
            z = x - center
            e3 = 0. * x

            theta = -_K[2]
            Rot = zeros((2, 2), float64)
            Rot[0, 0] = cos(theta)
            Rot[1, 0] = -sin(theta)
            Rot[0, 1] = -Rot[1, 0]
            Rot[1, 1] = Rot[0, 0]

            for p in range(2, 7):
                for i in Parts[p]:
                    [z[i], z[i + Nb]] = dot(Rot, [z[i], z[i + Nb]])
            x = z + center

            subMax = 1000.
            SubCount = 0
            while SubCount < 2:  #subMax > .000000000000001*_s:
                SubCount += 1

                FastForce(x[:Nb], x[Nb:], _f[:Nb], _f[Nb:], LinkIndices,
                          LinkData, LinkCurL, TetherIndex, TetherData)
                D = 0. * DSeed
                FastJacobian2(x, D, SeedArgs, LinkIndices, LinkData, LinkCurL,
                              TetherIndex, TetherData)
                f = F - _f

                e3 = 0. * x
                z = x - e1 * dot(x, e1) / dot(e1, e1) - e2 * dot(x, e2) / dot(
                    e2, e2)
                for p in range(2, 7):
                    for i in Parts[p]:
                        e3[i] = z[i + Nb]
                        e3[i + Nb] = -z[i]

                f -= e1 * dot(f, e1) / dot(e1, e1)
                f -= e2 * dot(f, e2) / dot(e2, e2)
                f -= e3 * dot(f, e3) / dot(e3, e3)
                subMax = max(list(abs(f)))
                if ShowStats:
                    print "    subRes:", subMax, .000000000000001 * _s

                ReduceD = Reduce * D * Reduce.T
                Dlu = scipy.linsolve.splu(ReduceD)
                y = Dlu.solve(Reduce * f) / _s
                #y = linsolve.spsolve(ReduceD, Reduce*f)
                y = Reduce.T * y

                y -= e1 * dot(y, e1) / dot(e1, e1)
                y -= e2 * dot(y, e2) / dot(e2, e2)
                y -= e3 * dot(y, e3) / dot(e3, e3)

                x += y

            FastForce(x[:Nb], x[Nb:], f[:Nb], f[Nb:], LinkIndices, LinkData,
                      LinkCurL, TetherIndex, TetherData)
            r = b + dot(dt * A, f) - x

            MaxRes = max(list(abs(r)))
            if ShowStats:
                print "  Residual:", MaxRes, "at time:", time.time() - Time

        FastForce(x[:Nb], x[Nb:], f[:Nb], f[Nb:], LinkIndices, LinkData,
                  LinkCurL, TetherIndex, TetherData)
        r = b + dot(dt * A, f) - x

        if ShowStats:
            print "Residual:", max(list(abs(r)))
    ##    print
    ##    print

        X, Y = 1. * x[0:Nb], 1. * x[Nb:2 * Nb]

        u, v = 1. * Old_u, 1. * Old_v
        ##    IB_c.CentralDerivative_x (N, M, h, u, ux)
        ##    IB_c.CentralDerivative_x (N, M, h, v, vx)
        ##    IB_c.CentralDerivative_y (N, M, h, u, uy)
        ##    IB_c.CentralDerivative_y (N, M, h, v, vy)

        Xss, Yss = FiberForce(Nb, X, Y, Xss, Yss, Links, Tethers)

        fx, fy = ForceToGrid(N, M, h, Nb, hb, Old_X, Old_Y, Xss, Yss)

        fx, fy = ExplicitTerms(dt, u, v, ux, uy, vx, vy, fx, fy)
        fx += dt * Current * ones((N, M), float64)

        fx = fft2(fx)
        fy = fft2(fy)

        P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
        P[0, 0] = 0.

        u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy)

        u = ifft2(u).real
        v = ifft2(v).real

        Xvel, Yvel = VelToFiber(N, M, h, Nb, hb, 1., Old_X, Old_Y, u, v)

        Time = time.time() - Time
        TotalTime += Time
        TotalCount += 1

        Ts = [.01, .02, .05, .1, .5]
        for _T in Ts:
            if CurT < _T and CurT + dt >= _T:
                print "Time", _T, ":", count, TotalTime, TotalTime / TotalCount
        #print "Time:", CurT
        CurT += dt

        print CurT, "Implicit:", Time

        count += 1
示例#18
0
x = zeros(2 * Nb, float64)

UField, VField, UField2, VField2 = InitVelField(N, N, h, h, dt)
print abs(UField).max(), abs(VField).max()
##print UField[0,0], UField[4,0], UField[0,0] - UField[4,0]
##raise
A = zeros((2 * Nb, 2 * Nb), float64)

u = zeros((N, N), float64)
v = zeros((N, N), float64)
fx = zeros((N, N), float64)
fy = zeros((N, N), float64)

WideLambda = zeros((N, N), float64)
ShortLambda = zeros((N, N), float64)
IB_c.InitWideLaplacian(N, N, h, WideLambda)
IB_c.InitShortLaplacian(N, N, h, ShortLambda)
DxSymbol = InitDxSymbol(N, N, h)
DySymbol = InitDySymbol(N, N, h)

########fx, fy = ForceToGrid (N, N, h, 1, 1, array([0],float64), array([0],float64), array([1],float64), array([0],float64))
########print fx[:,0]
########print sum(fx)
########
########fx = fft2(fx)
########fy = fft2(fy)
########
########P = Solve_P_Hat (dt, WideLambda, DxSymbol, DySymbol, fx, fy)
########P[0,0] = 0.
########
########u, v = Solve_uv_Hat (dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy)
def InitDySymbol(N, M, h):
    _DySymbol = zeros((N, M), float64)
    IB_c.InitDySymbol(N, M, h, _DySymbol)
    return 1j * _DySymbol
def InitVelField(_N, _M, _h, h, dt, rho=1., mu=1., DeltaType=0):
    WideLambda = zeros((_N, _M), float64)
    ShortLambda = zeros((_N, _M), float64)
    IB_c.InitWideLaplacian(_N, _M, _h, WideLambda)
    IB_c.InitShortLaplacian(_N, _M, _h, ShortLambda)
    DxSymbol = InitDxSymbol(_N, _M, _h)
    DySymbol = InitDySymbol(_N, _M, _h)

    r = int(ceil(3. * h / _h))

    fx = zeros((_N, _M), float64)
    for j in range(-r, r + 1):
        deltx = Delta(h, j * _h, DeltaType)
        for k in range(-r, r + 1):
            delt = deltx * Delta(h, k * _h, DeltaType) * 1.
            fx[j % _N][k % _M] = fx[j % _N][k % _M] + delt
#       print j%_N, k%_M, fx[j%_N][k%_M]

    fx, fy = fft2(dt * fx), zeros((_N, _M), float64)

    P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
    P[0, 0] = 0.

    u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy, rho,
                        mu)
    u = 1. * ifft2(u).real
    v = 1. * ifft2(v).real
    #    P = ifft2(P).real

    Fx1 = array(zeros((_N, _M), float64))
    Fy1 = array(zeros((_N, _M), float64))

    IB_c.WholeGridSpread(u, float(h), float(_h), int(r), Fx1, DeltaType)
    IB_c.WholeGridSpread(v, float(h), float(_h), int(r), Fy1, DeltaType)

    fy = zeros((_N, _M), float64)
    for j in range(-r, r + 1):
        deltx = Delta(h, j * _h, DeltaType)
        for k in range(-r, r + 1):
            delt = deltx * Delta(h, k * _h, DeltaType) * 1.
            fy[j % _N][k % _M] = fy[j % _N][k % _M] + delt

#       print j%_N, k%_M, fx[j%_N][k%_M]

    fx, fy = zeros((_N, _M), float64), fft2(dt * fy)

    P = Solve_P_Hat(dt, WideLambda, DxSymbol, DySymbol, fx, fy)
    P[0, 0] = 0.

    u, v = Solve_uv_Hat(dt, ShortLambda, DxSymbol, DySymbol, P, fx, fy, rho,
                        mu)
    u = 1. * ifft2(u).real
    v = 1. * ifft2(v).real

    Fx2 = array(zeros((_N, _M), float64))
    Fy2 = array(zeros((_N, _M), float64))

    IB_c.WholeGridSpread(u, float(h), float(_h), int(r), Fx2, DeltaType)
    IB_c.WholeGridSpread(v, float(h), float(_h), int(r), Fy2, DeltaType)

    return Fx1, Fy1, Fx2, Fy2
    return f


Domain_x, Domain_y = 1., 1.
N, M = 15, 15
h = 1. / N
print "N, M =", N, M
dt = .01
T = 5.
CurT = 0

_s = 5000000000.

WideLambda = zeros((N, M), float64)
ShortLambda = zeros((N, M), float64)
IB_c.InitWideLaplacian(N, M, h, WideLambda)
IB_c.InitShortLaplacian(N, M, h, ShortLambda)
DxSymbol = InitDxSymbol(N, M, h)
DySymbol = InitDySymbol(N, M, h)

_h = h
_N, _M = int(Domain_x / _h), int(Domain_y / _h)
UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt)

Nb = 2 * N
Xs = zeros(Nb, float64)
Ys = zeros(Nb, float64)
Xss = zeros(Nb, float64)
Yss = zeros(Nb, float64)
u = zeros((N, M), float64)
v = zeros((N, M), float64)
示例#22
0
Nb = 2*N #2*128
h = 1. / N
hb = 1. / Nb
dt = .001#.25 * .0015 / 2.
T = 1.
CurT = 0
mu = .05
rho = 1.
s = 1.

print "h:",h, ", dt:", dt


WideLambda = zeros((N,N),float64)
ShortLambda = zeros((N,N),float64)
IB_c.InitWideLaplacian(N, N, h, WideLambda)
IB_c.InitShortLaplacian(N, N, h, ShortLambda)
DxSymbol = InitDxSymbol(N, N, h)
DySymbol = InitDySymbol(N, N, h)

_h = h
_N, _M = int(1. / _h), int(1. / _h)
UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt, rho, mu)

print UField[0,0],VField2[0,0]

X = zeros(Nb, float64)
Y = zeros(Nb, float64)
Xs = zeros(Nb, float64)
Ys = zeros(Nb, float64)
Xss = zeros(Nb, float64)
示例#23
0
_h = 1. / _N
hb = 1. / Nb
dt = .0005
#dt = .02 * h
#dt = .00003 * h
T = .05
CurT = 0
s = 100000.
#s = 10000000.

print "h:",h, ", dt:", dt


WideLambda = zeros((N,N),float64)
ShortLambda = zeros((N,N),float64)
IB_c.InitWideLaplacian(N, N, h, WideLambda)
IB_c.InitShortLaplacian(N, N, h, ShortLambda)
DxSymbol = InitDxSymbol(N, N, h)
DySymbol = InitDySymbol(N, N, h)

_h = h
_N, _M = int(1. / _h), int(1. / _h)
UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt)

print UField[0,0],VField2[0,0]
clf()
clf(); imshow(UField); colorbar(); #show(); #&&raw_input("")
clf(); imshow(VField2); colorbar(); #show(); #&&raw_input("")


X = zeros(Nb, float64)
示例#24
0
    return VelToFiber(N, M, h, Nb, hb, 1., X, Y, u, v)


N = 256

All = AllDecompositions(root, N, Terms)
MaxDepth = len(All.UField)

Domain_x, Domain_y = 1., 1.
h = Domain_x / N
N, M = int(Domain_x / h), int(Domain_y / h)
dt = .002

WideLambda = zeros((N, M), float64)
ShortLambda = zeros((N, M), float64)
IB_c.InitWideLaplacian(N, M, h, WideLambda)
IB_c.InitShortLaplacian(N, M, h, ShortLambda)
DxSymbol = InitDxSymbol(N, M, h)
DySymbol = InitDySymbol(N, M, h)

_h = h
_N, _M = int(Domain_x / _h), int(Domain_y / _h)
UField, VField, UField2, VField2 = InitVelField(_N, _M, _h, h, dt)

##UField = ones((N,N),float64)

##UField = zeros((N,N), float64)
##for j in range(N):
##    for k in range(N):
##        UField[j,k] = cos(2*j*pi*h)