|
| 1 | +import math |
| 2 | +import matplotlib.pyplot as plt |
| 3 | +import tensorflow as tf |
| 4 | +import tensordiffeq as tdq |
| 5 | +from tensordiffeq.boundaries import * |
| 6 | +from tensordiffeq.models import CollocationSolverND |
| 7 | +from tensorflow.math import sin |
| 8 | +from tensordiffeq.utils import constant |
| 9 | + |
| 10 | +Domain = DomainND(["x", "y"]) |
| 11 | + |
| 12 | +Domain.add("x", [0, 1.0], 11) |
| 13 | +Domain.add("y", [0, 1.0], 11) |
| 14 | + |
| 15 | +N_f = 100 |
| 16 | +Domain.generate_collocation_points(N_f) |
| 17 | + |
| 18 | + |
| 19 | +def f_model(u_model, x, y): |
| 20 | + u = u_model(tf.concat([x, y], 1)) |
| 21 | + u_x = tf.gradients(u, x)[0] |
| 22 | + u_y = tf.gradients(u, y)[0] |
| 23 | + u_xx = tf.gradients(u_x, x)[0] |
| 24 | + u_yy = tf.gradients(u_y, y)[0] |
| 25 | + |
| 26 | + a1 = constant(1.0) |
| 27 | + a2 = constant(1.0) |
| 28 | + pi = constant(math.pi) |
| 29 | + |
| 30 | + # we use this specific forcing term because we have an exact analytical solution for this case |
| 31 | + # to compare the results of the PINN solution |
| 32 | + # note that we must use tensorflow math primitives such as sin, cos, etc! |
| 33 | + forcing = - sin(a1 * pi * x) * sin(a2 * pi * y) |
| 34 | + |
| 35 | + f_u = u_xx + u_yy - forcing # = 0 |
| 36 | + |
| 37 | + return f_u |
| 38 | + |
| 39 | + |
| 40 | +def func_upper_x(y): |
| 41 | + return -sin(constant(math.pi) * y) * sin(constant(math.pi)) |
| 42 | + |
| 43 | + |
| 44 | +def func_upper_y(x): |
| 45 | + return -sin(constant(math.pi) * x) * sin(constant(math.pi)) |
| 46 | + |
| 47 | + |
| 48 | +lower_x = dirichletBC(Domain, val=0.0, var='x', target="upper") |
| 49 | +upper_x = FunctionDirichletBC(Domain, fun=[func_upper_x], var='x', target="upper", func_inputs=["y"], n_values=10) |
| 50 | +upper_y = FunctionDirichletBC(Domain, fun=[func_upper_y], var='y', target="upper", func_inputs=["x"], n_values=10) |
| 51 | +lower_y = dirichletBC(Domain, val=0.0, var='y', target="lower") |
| 52 | + |
| 53 | +BCs = [upper_x, lower_x, upper_y, lower_y] |
| 54 | + |
| 55 | +layer_sizes = [2, 16, 16, 1] |
| 56 | + |
| 57 | +model = CollocationSolverND() |
| 58 | +model.compile(layer_sizes, f_model, Domain, BCs) |
| 59 | +model.tf_optimizer = tf.keras.optimizers.Adam(lr=.005) |
| 60 | +model.fit(tf_iter=4000) |
| 61 | + |
| 62 | +# get exact solution |
| 63 | +nx, ny = (11, 11) |
| 64 | +x = np.linspace(0, 1, nx) |
| 65 | +y = np.linspace(0, 1, ny) |
| 66 | + |
| 67 | +xv, yv = np.meshgrid(x, y) |
| 68 | + |
| 69 | +x = np.reshape(x, (-1, 1)) |
| 70 | +y = np.reshape(y, (-1, 1)) |
| 71 | + |
| 72 | +# Exact analytical soln is available: |
| 73 | +Exact_u = (np.sin(math.pi * xv) * np.sin(math.pi * yv)) / (2*math.pi**2) |
| 74 | + |
| 75 | +# Flatten for use |
| 76 | +u_star = Exact_u.flatten()[:, None] |
| 77 | + |
| 78 | +# Plotting |
| 79 | +x = Domain.domaindict[0]['xlinspace'] |
| 80 | +y = Domain.domaindict[1]["ylinspace"] |
| 81 | + |
| 82 | +X, Y = np.meshgrid(x, y) |
| 83 | + |
| 84 | +# print(np.shape((X,Y))) # 2, 256, 256 |
| 85 | +X_star = np.hstack((X.flatten()[:, None], Y.flatten()[:, None])) |
| 86 | + |
| 87 | +lb = np.array([0.0, 0.0]) |
| 88 | +ub = np.array([1.0, 1]) |
| 89 | + |
| 90 | +u_pred, f_u_pred = model.predict(X_star) |
| 91 | + |
| 92 | +#error_u = tdq.helpers.find_L2_error(u_pred, u_star) |
| 93 | +#print('Error u: %e' % (error_u)) |
| 94 | + |
| 95 | +U_pred = tdq.plotting.get_griddata(X_star, u_pred.flatten(), (X, Y)) |
| 96 | +FU_pred = tdq.plotting.get_griddata(X_star, f_u_pred.flatten(), (X, Y)) |
| 97 | + |
| 98 | +lb = np.array([0.0, 0.0]) |
| 99 | +ub = np.array([1.0, 1.0]) |
| 100 | + |
| 101 | +tdq.plotting.plot_solution_domain1D(model, [x, y], ub=ub, lb=lb, Exact_u=Exact_u) |
0 commit comments