Skip to content

Commit 4050a7f

Browse files
committed
update AC-discovery
1 parent d4bce28 commit 4050a7f

File tree

1 file changed

+41
-105
lines changed

1 file changed

+41
-105
lines changed

examples/AC-discovery.py

Lines changed: 41 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2,131 +2,67 @@
22
import tensorflow as tf
33
import scipy.io
44
import tensordiffeq as tdq
5-
from tensordiffeq.models import CollocationSolver1D
6-
from tensorflow.domain import DomainND
7-
import math
8-
from tensordiffeq.boundaries import IC, dirichlectBC, periodicBC
5+
from tensordiffeq.models import DiscoveryModel
6+
from tensordiffeq.utils import tensor
97

10-
def f_model(u_model, x, t):
11-
u = u_model(tf.concat([x,t],1))
12-
u_x = tf.gradients(u, x)
13-
u_xx = tf.gradients(u_x, x)
14-
u_t = tf.gradients(u,t)
15-
c1 = tdq.utils.constant(.0001)
16-
c2 = tdq.utils.constant(5.0)
17-
f_u = u_t - c1*u_xx + c2*u*u*u - c2*u
18-
return f_u
19-
20-
def u_x_model(u_model, x, t):
21-
u = u_model(tf.concat([x,t], 1))
22-
u_x = tf.gradients(u, x)
23-
return u, u_x
24-
25-
26-
N0 = 200
27-
NS = 200
28-
N_b = 100
29-
N_f = 20000
8+
#####################
9+
## Discovery Model ##
10+
#####################
3011

31-
Domain = DomainND(["x", "t"])
3212

33-
Domain.add("x", [-1,1], 512)
34-
Domain.add("t", [0,1], 100)
13+
# Put params into a list
14+
params = [tf.Variable(0.0, dtype=tf.float32), tf.Variable(0.0, dtype=tf.float32)]
3515

36-
def func_ic(x):
37-
return np.sin(x*math.pi)
38-
39-
BCs = [IC(Domain, func_ic, vars = 'x'),
40-
dirichlectBC(Domain, val = 0.0, vars = 'x', target = "upper"),
41-
dirichlectBC(Domain, val = 0.0, vars = 'x', target = "lower"),
42-
periodicBC(Domain, vars = 'x')]
43-
44-
col_weights = tf.Variable(tf.random.uniform([N_f, 1]))
45-
u_weights = tf.Variable(100*tf.random.uniform([N0, 1]))
46-
47-
# Grab collocation points using latin hpyercube sampling
48-
xlimits = np.array([[-1.0, 1.0], [0.0, 1.0]])
49-
X_f = tdq.LatinHypercubeSample(N_f, xlimits) #x_f, t_f
5016

17+
# Define f_model, note the `vars` argument. Inputs must follow this order!
18+
def f_model(u_model, var, x, t):
19+
u = u_model(tf.concat([x, t], 1))
20+
u_x = tf.gradients(u, x)
21+
u_xx = tf.gradients(u_x, x)
22+
u_t = tf.gradients(u, t)
23+
c1 = var[0] # tunable param 1
24+
c2 = var[1] # tunable param 2
25+
f_u = u_t - c1 * u_xx + c2 * u * u * u - c2 * u
26+
return f_u
5127

52-
lb = np.array([-1.0])
53-
ub = np.array([1.0])
5428

5529
# Import data, same data as Raissi et al
5630

5731
data = scipy.io.loadmat('AC.mat')
5832

59-
t = data['tt'].flatten()[:,None]
60-
x = data['x'].flatten()[:,None]
33+
t = data['tt'].flatten()[:, None]
34+
x = data['x'].flatten()[:, None]
6135
Exact = data['uu']
6236
Exact_u = np.real(Exact)
6337

64-
#grab training points from domain
65-
idx_x = np.random.choice(x.shape[0], N0, replace=False)
66-
x0 = x[idx_x,:]
67-
u0 = tf.cast(Exact_u[idx_x,0:1], dtype = tf.float32)
68-
69-
idx_xs = np.random.choice(x.shape[0], NS, replace=False) #need multiple Xs
70-
idx_ts = 100 #for 1 t value
71-
y_s = Exact[idx_xs, idx_ts]
72-
x_s = x[idx_xs,:]
73-
t_s = np.repeat(t[idx_ts,:], len(x_s))
74-
75-
y_s = tf.cast(tf.reshape(y_s, (-1,1)), dtype = tf.float32) #tensors need to be of shape (NS, 1), not (NS, )
76-
x_s = tdq.tensor(x_s)
77-
t_s = tf.cast(tf.reshape(t_s, (-1,1)), dtype = tf.float32)
78-
79-
idx_t = np.random.choice(t.shape[0], N_b, replace=False)
80-
tb = t[idx_t,:]
81-
82-
# Grab collocation points using latin hpyercube sampling
83-
x_f = tf.convert_to_tensor(X_f[:,0:1], dtype=tf.float32)
84-
t_f = tf.convert_to_tensor(np.abs(X_f[:,1:2]), dtype=tf.float32)
85-
86-
87-
X0 = np.concatenate((x0, 0*x0), 1) # (x0, 0)
88-
X_lb = np.concatenate((0*tb + lb[0], tb), 1) # (lb[0], tb)
89-
X_ub = np.concatenate((0*tb + ub[0], tb), 1) # (ub[0], tb)
90-
91-
x0 = tf.cast(X0[:,0:1], dtype = tf.float32)
92-
t0 = tf.cast(X0[:,1:2], dtype = tf.float32)
93-
94-
x_lb = tf.convert_to_tensor(X_lb[:,0:1], dtype=tf.float32)
95-
t_lb = tf.convert_to_tensor(X_lb[:,1:2], dtype=tf.float32)
96-
97-
x_ub = tf.convert_to_tensor(X_ub[:,0:1], dtype=tf.float32)
98-
t_ub = tf.convert_to_tensor(X_ub[:,1:2], dtype=tf.float32)
99-
38+
# define MLP depth and layer width
10039
layer_sizes = [2, 128, 128, 128, 128, 1]
101-
model = CollocationSolver1D(assimilate = True)
102-
103-
def g(lam):
104-
return lam**2
105-
106-
model.compile(layer_sizes, f_model, x_f, t_f, x0, t0, u0, x_lb, t_lb, x_ub, t_ub, isPeriodic=True, u_x_model=u_x_model)
107-
model.compile_data(x_s, t_s, y_s)
108-
109-
#train loop
110-
model.fit(tf_iter = 5000, newton_iter = 5000)
11140

112-
#generate meshgrid for forward pass of u_pred
113-
X, T = np.meshgrid(x,t)
41+
# generate all combinations of x and t
42+
X, T = np.meshgrid(x, t)
11443

115-
X_star = np.hstack((X.flatten()[:,None], T.flatten()[:,None]))
116-
u_star = Exact_u.T.flatten()[:,None]
44+
X_star = np.hstack((X.flatten()[:, None], T.flatten()[:, None]))
45+
u_star = Exact_u.T.flatten()[:, None]
11746

118-
u_pred, f_u_pred = model.predict(X_star)
47+
x = X_star[:, 0:1]
48+
t = X_star[:, 1:2]
11949

120-
error_u = tdq.find_L2_error(u_pred, u_star)
121-
print('Error u: %e' % (error_u))
50+
print(np.shape(x))
51+
# append to a list for input to model.fit
52+
X = [x, t]
12253

123-
U_pred = tdq.get_griddata(X_star, u_pred.flatten(), (X,T))
124-
FU_pred = tdq.get_griddata(X_star, f_u_pred.flatten(), (X,T))
54+
# define col_weights for SA discovery model
55+
col_weights = tf.Variable(tf.random.uniform([np.shape(x)[0], 1]))
12556

126-
lb = np.array([-1.0, 0.0])
127-
ub = np.array([1.0, 1])
57+
# initialize, compile, train model
58+
model = DiscoveryModel()
59+
model.compile(layer_sizes, f_model, X, u_star, params,
60+
col_weights=col_weights) # baseline approach can be done by simply removing the col_weights arg
61+
model.tf_optimizer_weights = tf.keras.optimizers.Adam(lr=0.005,
62+
beta_1=.95) # an example as to how one could modify an optimizer, in this case the col_weights optimizer
12863

129-
tdq.plotting.plot_solution_domain1D(model, [x, t], ub = ub, lb = lb, Exact_u=Exact_u)
64+
# train loop
65+
model.fit(tf_iter=10000)
13066

131-
extent = [0.0, 1.0, -1.0, 1.0]
132-
tdq.plotting.plot_residuals(FU_pred, extent)
67+
# doesnt work quite yet
68+
tdq.plotting.plot_weights(model, scale=10.0)

0 commit comments

Comments
 (0)