Mô hình ADCIRC
Tiến trình tìm hiểu và nghiên cứu về mô hình nước dâng do bão ADCIRC dưới sự hướng dẫn của thầy Nguyễn Quang Chiến
Bước đầu: dùng các dữ liệu của sẵn từ phần mềm ADCIRC với các fort dữ liệu chính
- fort.14 là dữ liệu của biên và điểm nút lưới tam giác
- fort.15 là dữ liệu hệ các hệ số thuỷ động học
- fort.61, fort.62 là dữ liệu giá trị mực nước theo 1 phương và 2 phương
- fort.63, fort.64 là giá trị độ sâu
Từ các dữ liệu trên tiến hành lập thuật toán với các dạng cơ bản trước:
- Đầu tiên: làm quen với ADCIRC để xác định các giá trị thời gian và độ cao đáy tại các nút với fort.14 và fort.15. Chạy kịch bản có sẵn quarter_annular_case:
TIME STEP = 1436 ITERATIONS = 7 TIME = 0.25848000E+06
ELMAX = -.5040E+00 AT NODE 21 SPEEDMAX = 0.1779E+00 AT NODE 40
TIME STEP = 1437 ITERATIONS = 7 TIME = 0.25866000E+06
ELMAX = -.5058E+00 AT NODE 21 SPEEDMAX = 0.1698E+00 AT NODE 40
TIME STEP = 1438 ITERATIONS = 7 TIME = 0.25884000E+06
ELMAX = -.5072E+00 AT NODE 21 SPEEDMAX = 0.1621E+00 AT NODE 41
TIME STEP = 1439 ITERATIONS = 7 TIME = 0.25902000E+06
ELMAX = -.5081E+00 AT NODE 21 SPEEDMAX = 0.1626E+00 AT NODE 41
TIME STEP = 1440 ITERATIONS = 7 TIME = 0.25920000E+06
ELMAX = -.5115E+00 AT NODE 2 SPEEDMAX = 0.1656E+00 AT NODE 41
+ lập thuật toán để vẽ ra 2 đường mực nước với 2 màu khác nhau và tên biểu đồ từ fort.61, cách bỏ qua các dòng trong fort.61.
f = io.open('fort.61', 'r')
. . .
for i = 1, 480 do
f:read()
f:read()
local _, mn = f:read('*n'), f:read('*n')
local _, mn2 = f:read('*n'), f:read('*n')
f:read()
print(i,mn, mn2)
if mn==nil then break end
table.insert(MN, tonumber(mn))
t:move_to(i-1, mn_cu)
t:line_to(i, mn)
p:add(t, 'blue', {{'stroke', width=1, cap='round'}})
mn_cu = mn
t2:move_to(i-1, mn2_cu)
t2:line_to(i, mn2)
t:close()
p:add(t2, 'red', {{'stroke', width=1, cap='round'}})
p.xtitle = 'chieu dai'
p.ytitle = 'muc nuoc'
p.title = 'Bieu do muc nuoc'
mn2_cu = mn2
end
f = io.open('fort.14', 'r')
. . .
for i = 1, nNode do
local _, x, y, z = f:read('*n'), f:read('*n'), f:read('*n'), f:read('*n')
print(i,x,y,z)
if x==nil or y==nil or z==nil then break end
table.insert(X, tonumber(x))
table.insert(Y, tonumber(y))
chu = graph.text( x, y, _)
p:add(chu)
end
for i = 1, nElem do
id, _,n1, n2, n3 = f:read('*n'), f:read('*n'), f:read('*n'), f:read('*n'), f:read('*n')
t = graph.path()
t:move_to(X[n1], Y[n1])
t:line_to(X[n2], Y[n2])
t:line_to(X[n3], Y[n3])
t:close()
p:add(t, 'red', {{'stroke', width=1, cap='round'}})
chu = graph.text((X[n1]+X[n2]+X[n3])/3, (Y[n1]+Y[n2]+Y[n3])/3, id)
p:add(chu)
end
hình minh họa:
+ tiếp theo thiết lập ma trận đơn giản để từ đó viết mã lệnh cho phân bố mực nước
io.write("Nhap vao so hang: "); M = io.read("*n")
io.write("nhap vao so cot: "); N = io.read("*n")
M2 = {}
-- Phat sinh bang
p = graph.plot()
for i=1 , M do
M2[i] = {}
for j=1, N do
M2[i][j] = (i+j)-1
end
end
t = graph.path()
t:move_to(i, j)
t:line_to(i+1, j)
t:line_to(i+1, j+1)
t:line_to(i, j+1)
t:close()
x=255*(i+j-1)/(M+N-1)
p:add(t, graph.rgb(x, x, x))
t1 = graph.path()
t1:move_to(2.5, 2.5)
t1:line_to(3.5, 2.5)
t1:line_to(3.5, 3.5)
t1:line_to(2.5, 3.5)
t1:close()
p:add(t1,'green')
end
+ dùng các thuật toán cơ bản biểu thị độ sâu theo màu sắc
t1 = graph.path()
t1:move_to(i-0.5, j-0.5)
t1:line_to(i-0.5, j+0.5)
t1:line_to(i+0.5, j+0.5)
t1:line_to(i+0.5, j-0.5)
t1:close()
x=255*(i+j-1)/(M+N-1)
p:add(t1, graph.rgb(x, x, x))
+ tiếp tục viết thuật toán cho phân bố mực nước với fort.63 từ dữ liệu có sẵn thiết lập lưới độ sâu bằng sự thay đổi màu sắc bởi các hàm, thao tác với độ sâu Zmax tìm trước bằng excel và thao tác bằng thuật toán với một khối dữ liệu bất kì
io.write("nhap vao khoi n: "); n = io.read("*n")
f = io.open('fort.14', 'r')
. . .
Nut1 = {}
Nut2 = {}
Nut3 = {}
for i = 1, nElem do
id, _,n1, n2, n3 = f:read('*n'), f:read('*n'), f:read('*n'), f:read('*n'), f:read('*n')
table.insert(Nut1, tonumber(n1))
table.insert(Nut2, tonumber(n2))
table.insert(Nut3, tonumber(n3))
. . .
f1 = io.open('fort.63', 'r')
f1:read() -- bo qua tieu de
f1:read() -- bo qua tieu de
f1:read() -- bo qua tieu de
for i=1, n*(nNode+1) do -- gom 1 dong thoi gian
f1:read()
end
. . .
Zmax=Z[1]
Zmin=Z[1]
for i=1, nNode do
if Z[i]>Zmax then Zmax=Z[i] end
if Z[i]<Zmin then Zmin=Z[i] end
end
print("Zmax:", Zmax)
print("Zmin:",Zmin)
for i = 1, nElem do
t = graph.path()
t:move_to(X[Nut1[i]], Y[Nut1[i]])
t:line_to(X[Nut2[i]], Y[Nut2[i]])
t:line_to(X[Nut3[i]], Y[Nut3[i]])
t:close()
Zptu = (Z[Nut1[i]]+Z[Nut2[i]]+Z[Nut3[i]])/3
p:add(t, graph.rgb(ThangMau(Zptu)))
end
ThangMau = function (Zptu)
z = (Zptu-Zmin)/(Zmax-Zmin)
if -0.01 <= z and z <= 0.25 then
r = ((z-0)/(0.25-0))*(0-0)+0
g = ((z-0)/(0.25-0))*(255-0)+0
b = ((z-0)/(0.25-0))*(0-128)+128
end
if 0.25 <= z and z <= 0.5 then
r = ((z-0.25)/(0.5-0.25))*(255-0)+0
g = ((z-0.25)/(0.5-0.25))*(255-255)+255
b = ((z-0.25)/(0.5-0.25))*(0-0)+0
end
if 0.5 <= z and z <=0.75 then
r = ((z-0.5)/(0.75-0.5))*(255-255)+255
g = ((z-0.5)/(0.75-0.5))*(128-255)+255
b = ((z-0.5)/(0.75-0.5))*(0-0)+0
end
if 0.75 <= z and z <= 1.01 then
r = ((z-0.75)/(1-0.75))*(255-255)+255
g = ((z-0.75)/(1-0.75))*(0-128)+128
b = ((z-0.75)/(1-0.75))*(0-0)+0
end
return r, g, b
end
hình minh họa:
+ lập lưới khống chế cho vùng thực tế cần nghiên cứu bằng cách dùng các hàm lập cho vùng đã được dựng sẵn trong gsl-shell và tìm hiểu thêm thông tin qua các thuật toán Delaunay: https://github.com/Yonaba/delaunay
f = io.open('diem.txt', 'r')
math.randomseed(1234)
for i = 1, 2773 do
x, y, z = f:read('*n'), f:read('*n'), f:read('*n')
x = x + math.random()*10
y = y + math.random()*10
points[i] = Point(x,y)
end
f:close()
-- Dao thu tu cac phan tu trong points
function shuffle(list)
local indices = {}
for i = 1, #list do
indices[#indices+1] = i
end
local shuffled = {}
for i = 1, #list do
local index = math.random(#indices)
local value = list[indices[index]]
table.remove(indices, index)
shuffled[#shuffled+1] = value
end
return shuffled
end
newpoints = shuffle(points)
...
print(triangles[1])
for key, value in pairs(triangles[1].p1) do
print(key)
end
f3 = io.open('tamgiac.txt', 'w')
for i = 1, #triangles do
f3:write(i, ' ', 3, ' ', triangles[i].p1.id, ' ', triangles[i].p2.id, ' ', triangles[i].p3.id, '\n')
end
f3:close()
Tìm và đánh dấu các đỉnh, nút của tam giác trong vùng giới hạn và in ra số liệu các nút để đưa vào fort.1 mới lập cho vùng thực tế.
Sau khi lập xong được lưới tam giác cho miền tính toán.
hình minh họa:
Thực tế cho thấy thư viện delaunay sẵn có của Lua rất hạn chế và không thể lập được lưới tam giác cho vùng phức tạp. Do vậy, nhóm nghiên cứu sử dụng thư viện Triangle trên nền Linux.
Áp dụng tính toán nước dâng do bão
Chọn miền tính toán có dạng chữ nhật đơn giản
...