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
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
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
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
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)
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
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)
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)
_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)
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)