@@ -3,7 +3,7 @@ module FlowOverCircle
3
3
using WaterLily, LinearAlgebra, ProgressMeter, MLUtils
4
4
using NeuralOperators, Flux, GeometricFlux, Graphs
5
5
using CUDA, FluxTraining, BSON
6
- using GeometricFlux. GraphSignals: generate_coordinates
6
+ using GeometricFlux. GraphSignals: generate_grid
7
7
8
8
function circle (n, m; Re = 250 ) # copy from [WaterLily](https://github.com/weymouth/WaterLily.jl)
9
9
# Set physical parameters
@@ -32,29 +32,21 @@ function gen_data(ts::AbstractRange)
32
32
return 𝐩s
33
33
end
34
34
35
- function get_dataloader (; ts:: AbstractRange = LinRange (100 , 11000 , 10000 ),
36
- ratio:: Float64 = 0.95 , batchsize = 100 , flatten = false )
35
+ function get_mno_dataloader (; ts:: AbstractRange = LinRange (100 , 11000 , 10000 ),
36
+ ratio:: Float64 = 0.95 , batchsize = 100 )
37
37
data = gen_data (ts)
38
38
𝐱, 𝐲 = data[:, :, :, 1 : (end - 1 )], data[:, :, :, 2 : end ]
39
39
n = length (ts) - 1
40
- grid = generate_coordinates (𝐱[1 , :, :, 1 ])
41
- grid = repeat (grid, outer = (1 , 1 , 1 , n))
42
- x_with_grid = vcat (𝐱, grid)
43
-
44
- if flatten
45
- x_with_grid = reshape (x_with_grid, size (x_with_grid, 1 ), :, n)
46
- 𝐲 = reshape (𝐲, 1 , :, n)
47
- end
48
40
49
- data_train, data_test = splitobs (shuffleobs ((x_with_grid , 𝐲)), at = ratio)
41
+ data_train, data_test = splitobs (shuffleobs ((𝐱 , 𝐲)), at = ratio)
50
42
51
43
loader_train = DataLoader (data_train, batchsize = batchsize, shuffle = true )
52
44
loader_test = DataLoader (data_test, batchsize = batchsize, shuffle = false )
53
45
54
46
return loader_train, loader_test
55
47
end
56
48
57
- function train (; cuda = true , η₀ = 1.0f-3 , λ = 1.0f-4 , epochs = 50 )
49
+ function train_mno (; cuda = true , η₀ = 1.0f-3 , λ = 1.0f-4 , epochs = 50 )
58
50
if cuda && CUDA. has_cuda ()
59
51
device = gpu
60
52
CUDA. allowscalar (false )
@@ -66,7 +58,7 @@ function train(; cuda = true, η₀ = 1.0f-3, λ = 1.0f-4, epochs = 50)
66
58
67
59
model = MarkovNeuralOperator (ch = (1 , 64 , 64 , 64 , 64 , 64 , 1 ), modes = (24 , 24 ),
68
60
σ = gelu)
69
- data = get_dataloader ()
61
+ data = get_mno_dataloader ()
70
62
optimiser = Flux. Optimiser (WeightDecay (λ), Flux. Adam (η₀))
71
63
loss_func = l₂loss
72
64
@@ -79,6 +71,61 @@ function train(; cuda = true, η₀ = 1.0f-3, λ = 1.0f-4, epochs = 50)
79
71
return learner
80
72
end
81
73
74
+ function batch_featured_graph (data, graph, batchsize)
75
+ tot_len = size (data)[end ]
76
+ bch_data = FeaturedGraph[]
77
+ for i in 1 : batchsize: tot_len
78
+ bch_rng = (i + batchsize >= tot_len) ? (i: tot_len) : (i: (i + batchsize - 1 ))
79
+ fg = FeaturedGraph (graph, nf = data[:, :, bch_rng], pf = data[:, :, bch_rng])
80
+ push! (bch_data, fg)
81
+ end
82
+
83
+ return bch_data
84
+ end
85
+
86
+ function batch_data (data, batchsize)
87
+ tot_len = size (data)[end ]
88
+ bch_data = Array{Float32, 3 }[]
89
+ for i in 1 : batchsize: tot_len
90
+ bch_rng = (i + batchsize >= tot_len) ? (i: tot_len) : (i: (i + batchsize - 1 ))
91
+ push! (bch_data, data[:, :, bch_rng])
92
+ end
93
+
94
+ return bch_data
95
+ end
96
+
97
+ function get_gno_dataloader (; ts:: AbstractRange = LinRange (100 , 11000 , 10000 ),
98
+ ratio:: Float64 = 0.95 , batchsize = 8 )
99
+ data = gen_data (ts)
100
+ 𝐱, 𝐲 = data[:, :, :, 1 : (end - 1 )], data[:, :, :, 2 : end ]
101
+ n = length (ts) - 1
102
+
103
+ # generate graph
104
+ graph = Graphs. grid (size (data)[2 : 3 ])
105
+
106
+ # add grid coordinates
107
+ grid = generate_coordinates (𝐱[1 , :, :, 1 ])
108
+ grid = repeat (grid, outer = (1 , 1 , 1 , n))
109
+ 𝐱 = vcat (𝐱, grid)
110
+
111
+ # flatten
112
+ 𝐱, 𝐲 = reshape (𝐱, size (𝐱, 1 ), :, n), reshape (𝐲, 1 , :, n)
113
+
114
+ data_train, data_test = splitobs (shuffleobs ((𝐱, 𝐲)), at = ratio)
115
+
116
+ batched_train_X = batch_featured_graph (data_train[1 ], graph, batchsize)
117
+ batched_test_X = batch_featured_graph (data_test[1 ], graph, batchsize)
118
+ batched_train_y = batch_data (data_train[2 ], batchsize)
119
+ batched_test_y = batch_data (data_test[2 ], batchsize)
120
+
121
+ loader_train = DataLoader ((batched_train_X, batched_train_y), batchsize = - 1 ,
122
+ shuffle = true )
123
+ loader_test = DataLoader ((batched_test_X, batched_test_y), batchsize = - 1 ,
124
+ shuffle = false )
125
+
126
+ return loader_train, loader_test
127
+ end
128
+
82
129
function train_gno (; cuda = true , η₀ = 1.0f-3 , λ = 1.0f-4 , epochs = 50 )
83
130
if cuda && CUDA. has_cuda ()
84
131
device = gpu
@@ -91,23 +138,17 @@ function train_gno(; cuda = true, η₀ = 1.0f-3, λ = 1.0f-4, epochs = 50)
91
138
92
139
grid_dim = 2
93
140
edge_dim = 2 (grid_dim + 1 )
94
- featured_graph = FeaturedGraph (grid ([96 , 64 ]))
95
- model = Chain (Flux. SkipConnection (Dense (grid_dim + 1 , 16 ), vcat),
96
- # size(x) = (19, 6144, 8)
97
- WithGraph (featured_graph,
98
- GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 )),
99
- WithGraph (featured_graph,
100
- GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 )),
101
- WithGraph (featured_graph,
102
- GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 )),
103
- WithGraph (featured_graph,
104
- GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 )),
105
- x -> x[1 : end - 3 , :, :],
141
+ model = Chain (GraphParallel (node_layer = Dense (grid_dim + 1 , 16 )),
142
+ GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 ),
143
+ GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 ),
144
+ GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 ),
145
+ GraphKernel (Dense (edge_dim, abs2 (16 ), gelu), 16 ),
146
+ node_feature,
106
147
Dense (16 , 1 ))
107
148
108
149
optimiser = Flux. Optimiser (WeightDecay (λ), Flux. Adam (η₀))
109
150
loss_func = l₂loss
110
- data = get_dataloader (batchsize = 8 , flatten = true )
151
+ data = get_gno_dataloader ( )
111
152
learner = Learner (model, data, optimiser, loss_func,
112
153
ToDevice (device, device),
113
154
Checkpointer (joinpath (@__DIR__ , " ../model/" )))
0 commit comments