Mô phỏng sóng Python

Đây là tập hợp các tập lệnh Matlab và Python để mô phỏng sự lan truyền sóng địa chấn ở dạng 1-D và 2-D. Sự truyền sóng dựa trên phương trình sóng âm bậc nhất trong công thức ứng suất-vận tốc (e. g. Virieux (1986)), được giải quyết bằng Sự khác biệt hữu hạn trên lưới so le

Nội dung

Trong kho lưu trữ này, các phiên bản 1-D và 2-D của mã mô phỏng sóng Hiệu số hữu hạn có sẵn trong Matlab và Python. Mã nguồn có thể được tìm thấy trong thư mục Matlab/, Python/JupyterNotebook, tương ứng

Các trật tự không gian cao hơn đạt được bằng cách mở rộng Taylor cổ điển

Đối với các đơn đặt hàng thời gian cao hơn, có hai phương pháp khả dụng

  1. Phương pháp Lax–Wendroff (chỉ trong 1-D). Học thuyết. Dablain (1986)

  2. Phương pháp Adams-Bashforth. Học thuyết. Bohlen & Wittkamp (2016)

Để khám phá ảnh hưởng của các thứ tự chính xác khác nhau, bạn có thể chạy tập lệnh FD_1D_compare hoặc FD_2D_compare

Ngoài ra, trong 1-D, có các tập lệnh để tính toán và vẽ đồ thị phân tán số cũng như phân tán số (phương pháp Adams-Bashforth) được cung cấp. Cho đến nay, tập lệnh này chỉ Matlab. Lý thuyết cơ bản được đưa ra trong Bohlen & Wittkamp (2016)

Văn học

  • Bohlen, T. , & Wittkamp, ​​F. (2016). Mô hình địa chấn sai phân hữu hạn miền thời gian ba chiều bằng cách sử dụng bộ tích hợp thời gian Adams–Bashforth so le. Tạp chí Địa vật lý Quốc tế, 204(3), 1781-1788

  • Dablain, M. MỘT. (1986). Ứng dụng của vi phân bậc cao cho phương trình sóng vô hướng. Địa vật lý, 51(1), 54-66

  • Virieux, J. (1986). Truyền sóng P-SV trong môi trường không đồng nhất. Phương pháp sai phân hữu hạn vận tốc-ứng suất. Địa vật lý, 51(4), 889-901

Giấy phép

Bộ sưu tập này có sẵn theo Giấy phép Công cộng GNU v3. 0. Xem tệp LICENCE để biết thêm thông tin

Project Planeverb là một công cụ âm thanh dựa trên sóng thời gian thực dựa trên CPU dành cho trò chơi. Nó đi kèm với sự tích hợp với Unity Engine

khái niệm sóng đa luồng cpu dsp bằng chứng xử lý tín hiệu số xử lý tín hiệu số unity-engine xử lý âm thanh âm học mô phỏng sóng hồi âm động cơ âm học

  • Cập nhật ngày 12 tháng 11 năm 2022
  • C++

timasjov / phương trình sóng 2d

Sao 8

  • Mã số
  • Vấn đề
  • Yêu cầu kéo

Mô phỏng phương trình sóng bằng phương pháp FDM và PCG

mô phỏng sóng pcg fdm bằng python

  • Cập nhật 15/03/2015
  • con trăn

sushant097 / Wave-Simulation-in-C-plus-plus

Sao 5

  • Mã số
  • Vấn đề
  • Yêu cầu kéo

Điều này dựa trên đồ họa. thư viện h thao tác Mô phỏng sóng cơ bản. Tại đây, bạn có thể vẽ sóng Hình sin, Sóng Cosine, Thêm Tín hiệu, Tạo sóng, v.v. và nhiều cái khác. Vui lòng kiểm tra đồ họa. chi nhánh h

c c-plus-plus khối mã lập trình đồ họa-thư viện đồ họa-phân tích tín hiệu mô phỏng sóng

  • Cập nhật ngày 6 tháng 3 năm 2022
  • C++

Alba-NR / Nereus_Code

Sao 1

  • Mã số
  • Vấn đề
  • Yêu cầu kéo

🌊Nereus. Công cụ kết xuất OpenGL C ++ hiện đại để hiển thị các đại dương thực tế trong thời gian thực. Nhìn vào kỹ thuật mô phỏng sóng và mô hình chiếu sáng nước. Dự án luận án năm thứ ba cho Tripos Khoa học Máy tính của Đại học Cambridge

phản xạ opengl cpp đại dương glsl tessname khúc xạ glsl-shaders mô phỏng sóng fresnel render-engine render-architecture

xin chào. Chào mừng các bạn đến với phần 2 của loạt bài hướng dẫn mô phỏng các hiện tượng tự nhiên bằng Python. Nếu bạn chưa xem phần 1, hãy chắc chắn rằng bạn đã làm như vậy, vì nó sẽ cung cấp nền tảng quan trọng về toán học đằng sau mô phỏng này. Tuy nhiên, nếu bạn coi mình là một người mới bắt đầu thành thạo trong phân tích số, thì rất có thể bạn sẽ ổn.

Mục tiêu của hướng dẫn này là mô phỏng một gợn nước khi nó phát triển theo thời gian. Đây sẽ là một điều thực sự thú vị, vì vậy hãy cố gắng

phương trình sóng

Nếu bạn tiếp xúc với vật lý, tôi chắc chắn rằng bạn biết một thực tế không thể phủ nhận rằng sóng liên tục ở xung quanh chúng ta. Cho dù thông qua bức xạ điện từ, âm thanh truyền trong không khí hay trong trường hợp này là gợn sóng do một giọt nước gây ra, sóng hoàn toàn có ở khắp mọi nơi. Mặc dù có nhiều dạng, nhưng có một điều luôn đúng với tất cả các sóng là các quy tắc vật lý nghiêm ngặt chi phối chúng. Về mặt toán học, tất cả các quy tắc vật lý này được cô đọng thành một phương trình đơn giản, một phương trình rất mạnh và đẹp đến mức được coi là một trong ba phương trình vi phân lớn. phương trình sóng

Phương trình sóng 2 chiều trong tọa độ Descartes

Phương trình sóng cho chúng ta biết bất kỳ sóng nào sẽ lan truyền trong không gian và phát triển theo thời gian như thế nào, bằng cách cung cấp cho chúng ta một hàm u(t, x, y) cho chúng ta chiều cao của sóng tại bất kỳ điểm nào (x, y) trong bất kỳ thời điểm nào. . Về cơ bản, nếu bạn nói phương trình sóng rằng bạn thả một quả bóng xuống ao, nó sẽ cho bạn biết gợn sóng do quả bóng tạo ra sẽ phát triển như thế nào theo thời gian và cho phép bạn dự đoán những thay đổi trong nước do nó gây ra. Tương tự như nếu bạn nói với phương trình sóng rằng bạn đã hét to hết mức có thể, nó sẽ cho bạn biết sóng âm thanh bạn tạo ra sẽ di chuyển và tương tác với môi trường của chúng như thế nào. Cuối cùng, bằng cách giải phương trình sóng, chúng ta sẽ có thể mô phỏng gợn sóng của mình một cách dễ dàng. Đó là một phương trình đẹp đến mức cần phải hiểu trước khi giải nó, nhưng nếu bạn chỉ quan tâm đến mô phỏng, vui lòng bỏ qua phần tiếp theo về trực giác

Trực giác

Hãy xem xét một lúc hai người ban đầu giữ chặt một sợi dây (màu đỏ) giữa họ, trước khi một người di chuyển tay lên xuống nhanh chóng, tạo ra một sóng khắp sợi dây

Sợi dây sau khi một làn sóng được gửi qua nó

Chụp nhanh sợi dây này sau khi sóng truyền qua nó, chúng tôi muốn tìm hiểu xem nó sẽ tiếp tục phát triển như thế nào theo thời gian. Vì lợi ích của ví dụ, chúng tôi giả sử một sợi dây không ma sát không có trọng lực. Để bắt đầu tiếp cận điều này, hãy bắt đầu bằng cách xác định một số biến

Các biến làm việc được hiển thị trực quan

Chiều cao của sợi dây tại vị trí x và thời điểm t sẽ được gọi là giá trị của hàm u(t, x). Với ý nghĩ đó, chúng tôi muốn xem xét điều gì có thể khiến sợi dây thay đổi theo thời gian. Vì chúng ta đã thiết lập không có trọng lực hay ma sát, nên lực duy nhất tác dụng lên sợi dây là lực căng, mà chúng ta có thể tưởng tượng lực này lớn nhất ở độ cao tối thiểu và tối đa của sợi dây

Lực căng thể hiện bởi hướng và độ lớn của mũi tên tím

Hơn nữa, có thể an toàn khi giả định rằng đối với các điểm dọc theo sợi dây càng xa giá trị độ cao tối thiểu và tối đa của nó thì lực căng càng yếu.

Lực căng vì nó liên quan đến độ lõm của dây

Về cơ bản, điều này đang đưa ra một tuyên bố về độ lõm, vì lực căng đạt mức cao nhất tại các điểm uốn cong cao dọc theo sợi dây và yếu đi khi chúng ra xa chúng hơn. Điều cuối cùng có thể được xác định ở đây là tại bất kỳ điểm nào dọc theo sợi dây, lực căng mà nó chịu tác dụng tỷ lệ thuận với độ lõm của nó. Vì phép tính 1 dạy chúng ta rằng độ lõm của một hàm được xác định bởi đạo hàm cấp hai của nó trong không gian, nên chúng ta có thể lập công thức đó

Trong đó k là hằng số tỷ lệ đơn giản. Bây giờ chúng ta phải tìm cách đặt lực theo u, và biến nó thành một thứ mà chúng ta có thể giải quyết và làm việc với. Nhìn vào định luật thứ hai của Newton, nó cho chúng ta biết rằng F = ma, cho phép thay thế nhanh chóng dẫn đến

Trong đó m là khối lượng tại điểm đó, a là gia tốc của nó, u là chiều cao của nó và k là hằng số tỷ lệ. Như vật lý cho chúng ta biết, gia tốc của bất kỳ hàm nào xử lý vị trí chỉ đơn giản là đạo hàm cấp hai của nó theo thời gian, điều đó có nghĩa là chúng ta có thể định nghĩa lại phương trình của mình là

Cuối cùng, vì k/m là một hằng số tùy ý, chúng ta có thể chỉ cần đặt toàn bộ thành một hằng số c khác, một hằng số để đảm bảo luôn dương, chúng ta bình phương. Dẫn đến dẫn xuất cuối cùng của chúng tôi là

Đây là phương trình sóng trong một chiều, nhưng đối với phiên bản hai chiều được minh họa ở trên cùng cũng như phiên bản mà chúng ta sẽ mô phỏng, lý thuyết vẫn giữ nguyên; . Đạo hàm cho chúng ta trực giác sâu sắc về một thực tế rằng vào cuối ngày, phương trình sóng chỉ đơn giản là cách toán học biểu thị chiều cao (hoặc biên độ) và độ dịch chuyển của chính sóng ảnh hưởng đến chuyển động của nó theo thời gian, chính xác là lý do tại sao vật lý trong video này

Bây giờ bạn đã hiểu phương trình sóng là gì và nó đến từ đâu, hãy bắt đầu giải nó

Rời rạc hóa phương trình sóng

Phương trình sóng 2 chiều trong tọa độ Descartes

Như đã thảo luận trong phần 1, nghiệm phân tích cho phương trình sóng cực kỳ khó đạt được và vì lợi ích của chúng ta, tốt hơn hết là chúng ta nên tính gần đúng nghiệm của nó hơn là tìm ra nghiệm chính xác của nó.

Như phần ôn lại nhanh của phần 1, khi chúng ta không thể giải một phương trình vi phân theo phương pháp phân tích, thay vào đó, chúng ta sử dụng các phương pháp số khác nhau để chia nhỏ phương trình đó thành một phương trình gần đúng mà chúng ta có thể giải. Trong phần trước chúng ta đã thảo luận về Phương pháp sai phân hữu hạn mà chúng ta sẽ sử dụng lại một lần nữa. Nói tóm lại, Phương pháp sai phân hữu hạn xấp xỉ một đạo hàm như

Nếu bạn chưa hoàn toàn quen thuộc với Phương pháp sai phân hữu hạn, hãy tưởng tượng nó là định nghĩa đại số cổ điển của một đạo hàm nhưng không có giới hạn, và thay vào đó là một không gian có kích thước hữu hạn dx ở giữa hai điểm

Hơn nữa, hãy nhớ xấp xỉ Sự khác biệt hữu hạn cho đạo hàm bậc hai là

Vì phương trình sóng liên quan đến hai đạo hàm bậc hai nên đây là phép tính gần đúng mà chúng ta sẽ chủ yếu sử dụng cho phần còn lại của hướng dẫn, nhưng hãy nhớ phiên bản sai phân hữu hạn của đạo hàm bậc nhất cho một bước tùy chọn sau này. Quá trình chia phương trình vi phân thành các phần gần đúng của nó được gọi là rời rạc hóa phương trình, mục tiêu cuối cùng là đưa phương trình về dạng mà chúng ta có thể giải cho bước tiếp theo trong thời gian chỉ khi biết thông tin về hiện tại.

Thay hai vế của phương trình sóng bằng các xấp xỉ sai phân hữu hạn của chúng, ta được

Bây giờ phương trình của chúng ta đã rời rạc, chúng ta có thể giải u(t+dt, x, y), lấy tích phân số thành công phương trình sóng. Một số kết quả đại số trong

Phương trình của chúng tôi được thiết lập để bằng cách biết thông tin tại thời điểm hiện tại t và thời điểm trước đó t-dt, chúng tôi có thể xác định các giá trị của u tại t+dt, có thể dự đoán trạng thái tương lai của sóng bằng cách chỉ biết hiện tại và trước đó . Bằng cách lặp lại qua nhiều thời điểm cách nhau bởi dt, chúng ta có thể phát triển làn sóng của mình đến tương lai xa như chúng ta mong muốn. Cùng với đó, chúng ta có phương trình ở trạng thái có thể giải được và có thể bắt đầu mã hóa mô phỏng

mô phỏng

Mô phỏng của chúng tôi sẽ liên quan đến một hồ nước hình vuông ban đầu bị xáo trộn ở trung tâm của nó trong một khoảng thời gian nhất định trước khi dừng lại

Hãy bắt đầu bằng cách xác định nhóm hình vuông của chúng ta dưới dạng một lưới các điểm được phân tách bằng dx và dy, trong đó Ly là tổng chiều cao và Lx là tổng chiều rộng. Việc tách nhóm thành lưới này được gọi là chia lưới miền của chúng tôi và sẽ cho phép các phương trình sai phân hữu hạn của chúng tôi hoạt động. Mỗi điểm trong lưới sẽ lưu trữ một giá trị cho u tại điểm đó. Mỗi một trong các mắt lưới này sẽ tồn tại cho mỗi bước thời gian chúng ta thực hiện, sao cho mảng cuối cùng sẽ lưu trữ các giá trị u của chúng ta sẽ là ba chiều, chiều đầu tiên cho thời gian và chiều thứ hai và thứ ba cho lưới

Trong mã, miền được chia lưới sẽ trông giống như

Lx = 10 # total width of the pool
Nx = 80
# amount of points in the x direction, the more the better
Ly = 10 # total height of the pool
Ny = 80
# amount of points in the y direction, the more the better
# meshes the x dimension of the domain as being from 0 to Lx and # containing Nx points. The linspace function returns an array of # all the points
x_vec = numpy.linspace(0, Lx, Nx)
dx = x_vec[2] - x_vec[1]
# defines dx as the space between 2 points

# meshes the y dimension of the domain as being from 0 to Ly and # containing Ny points. The linspace function returns an array of # all the points
y_vec = numpy.linspace(0, Ly, Ny)
dy = y_vec[2] - y_vec[1]
# defines dy as the space between 2 points

Bây giờ, miền không gian của chúng ta đã được chia lưới và chúng ta có dx và dy, tất cả những gì chúng ta cần để bắt đầu giải là c và dt

dt có thể được chọn và đây chỉ đơn giản là số phù hợp với tôi và c được giữ ở mức 1 để giữ cho phương trình đơn giản. Dt càng nhỏ càng tốt, vì nó sẽ cho kết quả mô phỏng chính xác hơn, mặc dù chậm hơn.

dt = .025 # the amount of time that will pass after every iteration
Nt = 4000
# amount of iterations
# this means that the simulation will simulate .025*4000 real # seconds of water ripplingc = 1 # keeping it simple# defines a 2 dimensional array that corresponds to the value of u at # every point in the mesh
u = numpy.zeros([Nt, len(x), len(y)])

Bởi vì phương trình của chúng tôi yêu cầu chúng tôi phải có u(t-dt, x, y) và u(t, x, y) đã được xác định để chúng tôi tính toán bước tiếp theo trong thời gian, nên chúng tôi cần xác định các điều kiện ban đầu của mình

Như đã đề cập trước đó, chúng tôi muốn có một sự xáo trộn ở trung tâm của nhóm (nơi có trung tâm (nx/2, ny/2)), vì vậy các điều kiện ban đầu của chúng tôi cho t-dt và t sẽ giống như

u[0, Nx // 2, Ny // 2] = numpy.sin(0) # disturbance at t = 0
u[1, Nx // 2, Ny // 2] = numpy.sin(1/10) # disturbance at t = 1

Vui lòng chơi xung quanh với những giá trị này, vì đây đơn giản là những gì phù hợp với tôi

Cuối cùng, để giải quyết tất cả những gì chúng ta phải làm là lặp lại theo thời gian và cắm tất cả các giá trị vào phương trình rời rạc, kết quả là

for t in range(1, Nt-1):
for x in range(1, Nx-1):
for y in range(1, Ny-1):
# continued disturbance in center for 100 steps
if (t < 100):
u[t, Nx // 2, Ny // 2] = numpy.sin(t / 10)
u[t+1, x, y] = c**2 * dt**2 * ( ((u[t, x+1, y] - 2*u[t, x, y] + u[t, x-1, y])/(dx**2)) + ((u[t, x, y+1] - 2*u[t, x, y] + u[t, x, y-1])/(dy**2)) ) + 2*u[t, x, y] - u[t-1, x, y]

Mặc dù giải pháp này hoạt động tốt, nhưng việc sử dụng ký hiệu mảng có nhiều mảng sẽ làm cho nó nhanh hơn rất nhiều, vì vậy nếu bạn đã quen với ký hiệu có nhiều mảng, hãy cân nhắc sử dụng nó thay thế. Lưu ý rằng nếu không có ký hiệu numpy, toàn bộ mô phỏng có thể mất tới một phút để tính toán đầy đủ

Vậy là xong, giờ bạn đã chính thức mô phỏng một gợn nước bằng cách giải phương trình sóng. để vẽ đồ thị giống như cách tôi đã làm ở trên cùng, chỉ cần lặp lại các giá trị đã tính toán và vẽ đồ thị bề mặt cho từng bước theo thời gian, bằng mã

fig = pyplot.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y = numpy.meshgrid(x_vec, y_vec)
for t in range(0, Nt):
surf = ax.plot_surface(X, Y, u[t], color='b', shade=True,
linewidth=0, antialiased=False)

ax.view_init(elev=45)
ax.set_zlim(-.0001, 2.4)
pyplot.axis('off')

pyplot.pause(.0001)
pyplot.cla()

Tất cả và tất cả, mã cuối cùng trông giống như

Không bắt buộc

Các bạn tinh ý có thể nhận thấy một chút khác biệt giữa mô phỏng ở trên cùng và mô phỏng bạn vừa tạo. Đây là nơi tôi đã để lại một chút nhiệm vụ. Ở trên cùng, phiên bản của phương trình sóng tôi đang giải bao gồm ma sát và được định nghĩa là

Trong đó v là hệ số ma sát. Hãy thử bằng cách sử dụng các phương pháp tương tự được nêu trong hướng dẫn này, cũng như phương pháp sai phân ngược, xác định một xấp xỉ thay thế của một đạo hàm là