コード例 #1
0
ファイル: stokes.py プロジェクト: lululxvi/hpinn
def main():
    geom = dde.geometry.Rectangle([0, 0], [1, 1])

    net = dde.maps.PFNN([2] + [[64] * 4] * 4 + [4], "tanh",
                        "Glorot normal")  # ?
    net.apply_output_transform(output_transform)

    losses = [
        dde.OperatorBC(geom, volume, lambda x, _: not geom.on_boundary(x)),
        dde.OperatorBC(
            geom, volume,
            lambda x, _: not geom.on_boundary(x)),  # augmented Lagrangian
        dde.OperatorBC(geom, dissipated_power,
                       lambda x, _: not geom.on_boundary(x)),
    ]

    dx = 0.01
    data = dde.data.PDE(
        geom,
        pde,
        losses,
        num_domain=int(geom.area / dx**2),
        num_boundary=int(geom.perimeter / dx),
    )
    model = dde.Model(data, net)

    mu_PDE, mu_V = 0.1, 1e4  # ?
    print("-" * 80)
    print(f"Iteration 0: mu = {mu_PDE}, {mu_V}\n")
    # loss_weights = [mu_PDE / 3] * 3 + [mu_V] + [1]  # penalty
    # loss = ["MSE", "MSE", "MSE", loss_volume, loss_power]
    loss_weights = [mu_PDE / 3] * 3 + [0] * 3 + [mu_V, 0] + [
        1
    ]  # augmented Lagrangian
    loss = ["MSE"] * 3 + ["zero"] * 3 + [loss_volume, "zero", loss_power]
    model.compile(
        "adam",
        lr=0.0001,
        loss=loss,
        loss_weights=loss_weights,
    )
    losshistory, train_state = model.train(epochs=20000)
    # save_solution(geom, model, "solution")
    # return
    model.compile(
        "L-BFGS-B",
        loss=loss,
        loss_weights=loss_weights,
    )
    losshistory, train_state = model.train()
    save_solution(geom, model, "solution0")

    augmented_Lagrangian(model, geom, mu_PDE, mu_V, 2)

    dde.saveplot(losshistory, train_state, issave=True, isplot=False)
コード例 #2
0
ファイル: Euler_beam.py プロジェクト: zzjzzjzp/deepxde
def main():
    def ddy(x, y):
        dy_x = tf.gradients(y, x)[0]
        return tf.gradients(dy_x, x)[0]

    def dddy(x, y):
        return tf.gradients(ddy(x, y), x)[0]

    def pde(x, y):
        dy_xxxx = tf.gradients(dddy(x, y), x)[0]
        return dy_xxxx + 1

    def boundary_l(x, on_boundary):
        return on_boundary and np.isclose(x[0], 0)

    def boundary_r(x, on_boundary):
        return on_boundary and np.isclose(x[0], 1)

    def func(x):
        return -x ** 4 / 24 + x ** 3 / 6 - x ** 2 / 4

    geom = dde.geometry.Interval(0, 1)

    zero_func = lambda x: np.zeros((len(x), 1))
    bc1 = dde.DirichletBC(geom, zero_func, boundary_l)
    bc2 = dde.NeumannBC(geom, zero_func, boundary_l)
    bc3 = dde.OperatorBC(geom, lambda x, y, _: ddy(x, y), boundary_r)
    bc4 = dde.OperatorBC(geom, lambda x, y, _: dddy(x, y), boundary_r)

    data = dde.data.PDE(
        geom,
        1,
        pde,
        [bc1, bc2, bc3, bc4],
        num_domain=10,
        num_boundary=2,
        func=func,
        num_test=100,
    )
    layer_size = [1] + [20] * 3 + [1]
    activation = "tanh"
    initializer = "Glorot uniform"
    net = dde.maps.FNN(layer_size, activation, initializer)

    model = dde.Model(data, net)
    model.compile("adam", lr=0.001, metrics=["l2 relative error"])
    losshistory, train_state = model.train(epochs=10000)

    dde.saveplot(losshistory, train_state, issave=True, isplot=True)
コード例 #3
0
ファイル: wave_1d.py プロジェクト: fabyayu/deepxde
def main():
    def pde(x, y):
        dy_tt = dde.grad.hessian(y, x, i=1, j=1)
        dy_xx = dde.grad.hessian(y, x, i=0, j=0)
        return dy_tt - C**2 * dy_xx

    def func(x):
        x, t = np.split(x, 2, axis=1)
        return np.sin(np.pi * x) * np.cos(C * np.pi * t) + np.sin(
            A * np.pi * x) * np.cos(A * C * np.pi * t)

    geom = dde.geometry.Interval(0, 1)
    timedomain = dde.geometry.TimeDomain(0, 1)
    geomtime = dde.geometry.GeometryXTime(geom, timedomain)

    bc = dde.DirichletBC(geomtime, func, lambda _, on_boundary: on_boundary)
    ic_1 = dde.IC(geomtime, func, lambda _, on_initial: on_initial)
    # do not use dde.NeumannBC here, since `normal_derivative` does not work with temporal coordinate.
    ic_2 = dde.OperatorBC(
        geomtime,
        lambda x, y, _: dde.grad.jacobian(y, x, i=0, j=1),
        lambda x, _: np.isclose(x[1], 0),
    )
    data = dde.data.TimePDE(
        geomtime,
        pde,
        [bc, ic_1, ic_2],
        num_domain=360,
        num_boundary=360,
        num_initial=360,
        solution=func,
        num_test=10000,
    )

    layer_size = [2] + [100] * 3 + [1]
    activation = "tanh"
    initializer = "Glorot uniform"
    net = dde.maps.STMsFFN(layer_size,
                           activation,
                           initializer,
                           sigmas_x=[1],
                           sigmas_t=[1, 10])
    net.apply_feature_transform(lambda x: (x - 0.5) * 2 * np.sqrt(3))

    model = dde.Model(data, net)
    initial_losses = get_initial_loss(model)
    loss_weights = 5 / initial_losses
    model.compile(
        "adam",
        lr=0.001,
        metrics=["l2 relative error"],
        loss_weights=loss_weights,
        decay=("inverse time", 2000, 0.9),
    )
    pde_residual_resampler = dde.callbacks.PDEResidualResampler(period=1)
    losshistory, train_state = model.train(epochs=10000,
                                           callbacks=[pde_residual_resampler],
                                           display_every=500)

    dde.saveplot(losshistory, train_state, issave=True, isplot=True)
コード例 #4
0
def main():
    # In some GPUs, float64 is required to make L-BFGS work for some reason... 
    # dde.config.real.set_float64()

    geom = dde.geometry.Rectangle(BOX[0] - DPML, BOX[1] + DPML)
    geom1 = dde.geometry.Rectangle(BOX[0] - DPML, [BOX[1][0] + DPML, -1])
    geom2 = dde.geometry.Rectangle([BOX[0][0] - DPML, -1], [BOX[1][0] + DPML, 0])
    geom3 = dde.geometry.Rectangle([BOX[0][0] - DPML, 0], BOX[1] + DPML)
    geom3_small = dde.geometry.Rectangle([BOX[0][0], 0], BOX[1])
    # geom3_in = dde.geometry.Rectangle([-0.5, 1], [0.5, 2])
    # geom3_out = geom3 - geom3_in

    net = dde.maps.PFNN([2] + [[48] * 3] * 4 + [3], "tanh", "Glorot normal")
    net.apply_feature_transform(feature_transform)
    net.apply_output_transform(output_transform)

    # Fit to the planewave solution
    # E0 = np.loadtxt("E0_normal.dat")
    # E0 = E0[np.random.choice(len(E0), size=10000, replace=False)]
    # ptset = dde.bc.PointSet(E0[:, :2])
    # inside = lambda x, _: ptset.inside(x)
    # loss0 = [
    #     dde.DirichletBC(geom, ptset.values_to_func(E0[:, 2:3]), inside, component=0),
    #     dde.DirichletBC(geom, ptset.values_to_func(E0[:, 3:4]), inside, component=1),
    #     dde.DirichletBC(geom, ptset.values_to_func(E0[:, 4:5]), inside, component=2),
    # ]

    # data = dde.data.PDE(geom, pde_domain, loss0, anchors=E0[:, :2])
    # model = dde.Model(data, net)
    # checkpointer = dde.callbacks.ModelCheckpoint(
    #     "model/model.ckpt", verbose=1, save_better_only=True
    # )
    # model.compile("adam", lr=0.001, loss_weights=[0] * 2 + [10] * 2 + [0.1])
    # losshistory, train_state = model.train(epochs=3000)
    # model.compile("adam", lr=0.001, loss_weights=[1] * 2 + [10] * 2 + [0])
    # losshistory, train_state = model.train(
    #     epochs=10000, callbacks=[checkpointer], disregard_previous_best=True
    # )
    # model.compile("L-BFGS-B", loss_weights=[1] * 2 + [10] * 2 + [0])
    # losshistory, train_state = model.train(callbacks=[checkpointer])
    # dde.saveplot(losshistory, train_state, issave=True, isplot=False)
    # save_solution(geom, model)
    # return

    losses = []
    # PDE (3)
    # losses += [
    #     dde.OperatorBC(geom, pde_E1_ReIm, lambda x, _: geom1.inside(x)),
    #     dde.OperatorBC(geom, pde_E2_ReIm, lambda x, _: geom2.inside(x)),
    #     dde.OperatorBC(geom, pde_E3_ReIm, lambda x, _: geom3.inside(x)),
    # ]

    # PML BC
    # Periodic BC (12)
    # losses += [
    #     dde.PeriodicBC(geom, 0, boundary1_leftright, derivative_order=0, component=0),
    #     dde.PeriodicBC(geom, 0, boundary1_leftright, derivative_order=1, component=0),
    #     dde.PeriodicBC(geom, 0, boundary1_leftright, derivative_order=0, component=1),
    #     dde.PeriodicBC(geom, 0, boundary1_leftright, derivative_order=1, component=1),
    #     dde.PeriodicBC(geom, 0, boundary2, derivative_order=0, component=2),
    #     dde.PeriodicBC(geom, 0, boundary2, derivative_order=1, component=2),
    #     dde.PeriodicBC(geom, 0, boundary2, derivative_order=0, component=3),
    #     dde.PeriodicBC(geom, 0, boundary2, derivative_order=1, component=3),
    #     dde.PeriodicBC(geom, 0, boundary3_leftright, derivative_order=0, component=4),
    #     dde.PeriodicBC(geom, 0, boundary3_leftright, derivative_order=1, component=4),
    #     dde.PeriodicBC(geom, 0, boundary3_leftright, derivative_order=0, component=5),
    #     dde.PeriodicBC(geom, 0, boundary3_leftright, derivative_order=1, component=5),
    # ]
    # Dirichlet BC (4)
    # losses += [
    #     dde.DirichletBC(geom, lambda _: 0, boundary1_bottom, component=0),
    #     dde.DirichletBC(geom, lambda _: 0, boundary1_bottom, component=1),
    #     dde.DirichletBC(geom, lambda _: 0, boundary3_top, component=4),
    #     dde.DirichletBC(geom, lambda _: 0, boundary3_top, component=5),
    # ]

    # Interface between Omega_1 and Omega_2 (4)
    # losses += [
    #     dde.OperatorBC(geom, interface12_ReE, interface12),
    #     dde.OperatorBC(geom, interface12_ImE, interface12),
    #     dde.OperatorBC(geom, interface12_dReE, interface12),
    #     dde.OperatorBC(geom, interface12_dImE, interface12),
    # ]
    # Interface between Omega_2 and Omega_3 (4)
    # losses += [
    #     dde.OperatorBC(geom, interface23_ReE, interface23),
    #     dde.OperatorBC(geom, interface23_ImE, interface23),
    #     dde.OperatorBC(geom, interface23_dReE, interface23),
    #     dde.OperatorBC(geom, interface23_dImE, interface23),
    # ]

    # Target (2)
    losses += [
        dde.OperatorBC(geom, target_bc, lambda x, _: geom3_small.inside(x)),
        # dde.OperatorBC(geom, target1, lambda x, _: geom3_in.inside(x)),
        # dde.OperatorBC(geom, target0, lambda x, _: geom3_out.inside(x)),
    ]

    # Points
    dx = 0.05
    # Extra points
    # h = 0.6
    # g = dde.geometry.Rectangle(
    #     [BOX[0][0] - DPML, -1.5 - h], [BOX[1][0] + DPML, -1.5 + h]
    # )
    # anchors = g.random_points(int(g.area / (dx / 4) ** 2))

    data = dde.data.PDE(
        geom,
        pde_domain,
        # None,
        losses,
        # [],
        num_domain=int(geom.area / dx ** 2),
        num_boundary=int(geom.perimeter / dx),
        # anchors=anchors,
        # num_test=50000,
        # solution=solution_forward,
    )
    model = dde.Model(data, net)

    # loss_weights = [0.5] * 2
    mu = 2
    print("-" * 80)
    print(f"Iteration 0: mu = {mu}\n")
    # loss_weights = [0.5 * mu] * 2 + [1]  # penalty
    loss_weights = [0.5 * mu] * 2 + [0, 0] + [1]  # augmented_Lagrangian
    model.compile(
        "adam",
        lr=0.001,
        loss_weights=loss_weights,
        # metrics=[l2_relative_error_1, l2_relative_error_2],
    )
    losshistory, train_state = model.train(epochs=20000)
    # save_epsilon(geom2, model, "epsilon_init.dat")
    # return
    model.compile(
        "L-BFGS-B",
        loss_weights=loss_weights,
        # metrics=[l2_relative_error_1, l2_relative_error_2],
    )
    losshistory, train_state = model.train()
    save_epsilon(geom2, model, "epsilon0.dat")
    # save_solution(geom, model, "E0.dat", "residual0.dat")

    # penalty(model, geom2, mu, 2)
    augmented_Lagrangian(model, geom, geom2, mu, 2)

    dde.saveplot(losshistory, train_state, issave=True, isplot=False)
コード例 #5
0
def main(train=True, test=True):
    # case name
    case_name = "unNACA0012_inlet_bc_zero_forcings_zero_curl"
    case_name_title = r'PIV stride $0.01 \times 0.01$ big domain f0 zero inlet curl forcings 0 at inlet'

    set_directory(case_name)

    x_data, y_data, u_data, v_data, p_data, uu_data, uv_data, vv_data, x_domain, y_domain = read_data(
    )

    airfoil_points = read_airfoil("./Data/points_ok.dat")
    airfoil_array = np.array(airfoil_points)
    airfoil_array = rotate_points(airfoil_array[:, 0], airfoil_array[:, 1],
                                  0.5, 0, -15 / 180 * math.pi)

    airfoil_points = airfoil_array.tolist()

    #domain vertices
    v_ld = [-0.3, -0.6]
    v_ru = [2.7, 0.6]
    figsize = (10, 10 * (v_ru[1] - v_ld[1]) / (v_ru[0] - v_ld[0]))
    figsize = (8, 3)

    Nx = int((v_ru[0] - v_ld[0]) * 500) + 1
    Ny = int((v_ru[1] - v_ld[1]) * 500) + 1
    print('Nx', Nx, 'Ny', Ny)

    # geometry specification
    geom1 = dde.geometry.Polygon(airfoil_points)
    geom2 = dde.geometry.Rectangle(v_ld, v_ru)
    geom = geom2 - geom1

    [x_piv, y_piv, u_piv, v_piv, p_piv] = \
        generate_PIV_points(x_data, y_data, u_data, v_data,
                            p_data, 10, 10, v_ld, v_ru, geom, True)
    piv_points = np.hstack((x_piv, y_piv))

    # print(piv_points.shape)
    # exit(0)

    # BC specification
    # boundaries functions
    def boundary(x, on_boundary):
        return on_boundary and not (np.isclose(x[0], v_ld[0]) or np.isclose(
            x[0], v_ru[0]) or np.isclose(x[1], v_ld[1])
                                    or np.isclose(x[1], v_ru[1]))

    def boundary_left_free(x, on_boundary):
        return on_boundary and (np.isclose(x[0], v_ld[0]) or
                                (np.isclose(x[1], v_ru[1]) and x[0] <= -0.3) or
                                (np.isclose(x[1], v_ld[1]) and x[0] <= -0.3))

    def boundary_left_full(x, on_boundary):
        return on_boundary and not (
            np.isclose(x[0], v_ru[0]) or
            (np.isclose(x[1], v_ru[1]) and x[0] > -0.3) or
            (np.isclose(x[1], v_ld[1]) and x[0] > -0.3))

    def curl_f_func(X, V, X_values):
        dfsx_y = dde.grad.jacobian(V, X, i=3, j=1)
        dfsy_x = dde.grad.jacobian(V, X, i=4, j=0)
        return dfsy_x - dfsx_y

    # BC objects
    u_piv_points = dde.PointSetBC(piv_points, u_piv, component=0)
    v_piv_points = dde.PointSetBC(piv_points, v_piv, component=1)
    bc_wall_u = dde.DirichletBC(geom, func_zeros, boundary, component=0)
    bc_wall_v = dde.DirichletBC(geom, func_zeros, boundary, component=1)
    bc_wall_fx = dde.DirichletBC(geom,
                                 func_zeros,
                                 boundary_left_full,
                                 component=3)
    bc_wall_fy = dde.DirichletBC(geom,
                                 func_zeros,
                                 boundary_left_full,
                                 component=4)
    bc_curl_fs = dde.OperatorBC(geom, curl_f_func, boundary_left_free)

    # custom domain points
    domain_points = generate_domain_points(x_domain, y_domain, geometry=geom)

    # pde and physics compilation
    pde = RANSf02D(500)
    if train:
        data = dde.data.PDE(
            geom,
            pde,
            [
                bc_wall_u, bc_wall_v, bc_wall_fx, bc_wall_fy, bc_curl_fs,
                u_piv_points, v_piv_points
            ],
            100,
            1600,
            solution=None,
            num_test=100,
            train_distribution="custom",
            custom_train_points=domain_points,
        )
        plot_train_points(
            data, [2, 4, 5, 7],
            ["airfoil velocities", "forcing", "curl forcing", "piv"],
            case_name,
            title=case_name_title,
            figsize=figsize)
    else:
        data = dde.data.PDE(geom,
                            pde, [
                                bc_wall_u, bc_wall_v, bc_wall_fx, bc_wall_fy,
                                bc_curl_fs, u_piv_points, v_piv_points
                            ],
                            100,
                            100,
                            solution=None,
                            num_test=100)
    # exit(0)
    # NN model definition
    layer_size = [2] + [100] * 7 + [5]
    activation = "tanh"
    initializer = "Glorot uniform"
    net = dde.maps.FNN(layer_size, activation, initializer)

    # PINN definition
    model = dde.Model(data, net)

    if train:
        # Adam optimization
        loss_weights = [1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 10]
        model.compile("adam", lr=0.001, loss_weights=loss_weights)
        checkpointer = dde.callbacks.ModelCheckpoint(
            f"{case_name}/models/model_{case_name}.ckpt",
            verbose=1,
            save_better_only=True,
        )

        loss_update = dde.callbacks.LossUpdateCheckpoint(
            momentum=0.7,
            verbose=1,
            period=1,
            report_period=100,
            base_range=[0, 1, 2, 3],
            update_range=[4, 5, 6, 7, 8, 9, 10])
        print('Training for 20000 epochs')
        losshistory, train_state = model.train(
            epochs=20000,
            callbacks=[checkpointer, loss_update],
            display_every=100)

        model.save(f"{case_name}/models/model-adam-last")

        # L-BFGS-B optimization
        model.compile("L-BFGS-B", loss_weights=loss_weights)
        losshistory, train_state = model.train()
        model.save(f"{case_name}/models/model-bfgs-last")

    if test:
        model.compile("adam", lr=0.001)
        model.compile("L-BFGS-B")
        last_epoch = model.train_state.epoch
        if not train:
            last_epoch = 50001
        model.restore(f"{case_name}/models/model-bfgs-last-{last_epoch}")

        x_plot = np.linspace(v_ld[0], v_ru[0], Nx)
        y_plot = np.linspace(v_ld[1], v_ru[1], Ny)
        # domain data
        x_data = x_data.reshape(1501, 601).T
        y_data = y_data.reshape(1501, 601).T
        u_data = u_data.reshape(1501, 601).T
        v_data = v_data.reshape(1501, 601).T
        p_data = p_data.reshape(1501, 601).T
        x_dom = np.linspace(-0.3, 2.7, 1501)
        y_dom = np.linspace(-0.6, 0.6, 601)
        x_min = np.argmin(np.abs(x_dom - v_ld[0]))
        x_max = np.argmin(np.abs(x_dom - v_ru[0]))
        y_min = np.argmin(np.abs(y_dom - v_ld[1]))
        y_max = np.argmin(np.abs(y_dom - v_ru[1]))
        print(x_min, x_max, y_min, y_max)
        x_data = x_data[y_min:y_max + 1, x_min:x_max + 1].T.reshape(-1, 1)
        y_data = y_data[y_min:y_max + 1, x_min:x_max + 1].T.reshape(-1, 1)
        u_data = u_data[y_min:y_max + 1, x_min:x_max + 1].T.reshape(-1, 1)
        v_data = v_data[y_min:y_max + 1, x_min:x_max + 1].T.reshape(-1, 1)
        p_data = p_data[y_min:y_max + 1, x_min:x_max + 1].T.reshape(-1, 1)

        z = np.array([np.array([i, j]) for i in x_plot for j in y_plot])
        y = model.predict(z)
        u_star = y[:, 0][:, None]
        v_star = y[:, 1][:, None]
        p_star = y[:, 2][:, None]
        fx_star = y[:, 3][:, None]
        fy_star = y[:, 4][:, None]

        data_dict = {
            "u_star": u_star,
            "v_star": v_star,
            "p_star": p_star,
            "fx_star": fx_star,
            "fy_star": fy_star
        }
        scipy.io.savemat(f"{case_name}/results.mat", data_dict)

        zero_index = (x_data < 0) & (x_data > 0)
        zero_index = zero_index | ((u_data == 0) & (v_data == 0))
        no_data_index = zero_index

        u_star_data = deepcopy(u_star)
        v_star_data = deepcopy(v_star)
        p_star_data = deepcopy(p_star)
        fx_star_data = deepcopy(fx_star)
        fy_star_data = deepcopy(fy_star)

        u_star_data[no_data_index] = u_star[no_data_index] * 0
        v_star_data[no_data_index] = v_star[no_data_index] * 0
        p_star_data[no_data_index] = p_star[no_data_index] * 0
        fx_star_data[no_data_index] = fx_star[no_data_index] * 0
        fy_star_data[no_data_index] = fy_star[no_data_index] * 0

        u_star_data = u_star_data.reshape(Nx, Ny).T
        v_star_data = v_star_data.reshape(Nx, Ny).T
        p_star_data = p_star_data.reshape(Nx, Ny).T
        fx_star_data = fx_star_data.reshape(Nx, Ny).T
        fy_star_data = fy_star_data.reshape(Nx, Ny).T

        X, Y = np.meshgrid(x_plot, y_plot)
        plt.figure(figsize=figsize)
        # plt.title(f'regressed u field for {case_name_title}')
        plt.pcolor(X, Y, u_star_data)
        plt.colorbar(label='u')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'u_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'regressed v field for {case_name_title}')
        plt.pcolor(X, Y, v_star_data)
        plt.colorbar(label='v')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'v_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'regressed p field for {case_name_title}')
        plt.pcolor(X, Y, p_star_data)
        plt.colorbar(label='p')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'p_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'regressed fx field for {case_name_title}')
        plt.pcolor(X, Y, fx_star_data)
        plt.colorbar(label='fx')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'fx_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'regressed fy field for {case_name_title}')
        plt.pcolor(X, Y, fy_star_data)
        plt.colorbar(label='fy')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'fy_plot.png'),
                    dpi=400)
        plt.close()

        # data error
        u_star_data = deepcopy(u_star)
        v_star_data = deepcopy(v_star)
        p_star_data = deepcopy(p_star)
        u_star_data[no_data_index] = u_star[no_data_index] * 0
        v_star_data[no_data_index] = v_star[no_data_index] * 0
        p_star_data[no_data_index] = p_star[no_data_index] * 0

        u_star_data = u_star_data.reshape(Nx, Ny).T
        v_star_data = v_star_data.reshape(Nx, Ny).T
        p_star_data = p_star_data.reshape(Nx, Ny).T

        u_true = None
        v_true = None
        p_true = None

        u_true = deepcopy(u_data)
        v_true = deepcopy(v_data)
        p_true = deepcopy(p_data)

        u_true = u_true.reshape(Nx, Ny).T
        v_true = v_true.reshape(Nx, Ny).T
        p_true = p_true.reshape(Nx, Ny).T
        u_err = np.abs(u_true - u_star_data)
        v_err = np.abs(v_true - v_star_data)
        p_err = np.abs(p_true - p_star_data)

        plt.figure(figsize=figsize)
        # plt.title(f'u field abs error for {case_name_title}')
        plt.pcolor(X, Y, u_err)
        plt.colorbar(label='u')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'u_err_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'v field abs error for {case_name_title}')
        plt.pcolor(X, Y, v_err)
        plt.colorbar(label='v')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'v_err_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'p field abs error for {case_name_title}')
        plt.pcolor(X, Y, p_err)
        plt.colorbar(label='p')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'p_err_plot.png'),
                    dpi=400)
        plt.close()

        e = model.predict(z, operator=pde)
        e_mass = e[0]
        e_u_momentum = e[1]
        e_v_momentum = e[2]
        f_divergence = e[3]

        data_dict.update({
            "e_mass": e_mass,
            "e_u_momentum": e_u_momentum,
            "e_v_momentum": e_v_momentum,
            "f_divergence": f_divergence
        })
        scipy.io.savemat(f"{case_name}/results.mat", data_dict)

        e_mass[no_data_index] = e_mass[no_data_index] * 0
        e_u_momentum[no_data_index] = e_u_momentum[no_data_index] * 0
        e_v_momentum[no_data_index] = e_v_momentum[no_data_index] * 0
        f_divergence[no_data_index] = f_divergence[no_data_index] * 0
        e_mass = e_mass.reshape(Nx, Ny).T
        e_u_momentum = e_u_momentum.reshape(Nx, Ny).T
        e_v_momentum = e_v_momentum.reshape(Nx, Ny).T
        f_divergence = f_divergence.reshape(Nx, Ny).T

        plt.figure(figsize=figsize)
        # plt.title(f'mass conservation residual for {case_name_title}')
        plt.pcolor(X, Y, e_mass, vmin=-1, vmax=1)
        plt.colorbar(label='e_mass')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'e_mass_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'u momentum conservation residual for {case_name_title}')
        plt.pcolor(X, Y, e_u_momentum, vmin=-1, vmax=1)
        plt.colorbar(label='e_u_momentum')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots',
                                 'e_u_momentum_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'v momentum conservation residual for {case_name_title}')
        plt.pcolor(X, Y, e_v_momentum, vmin=-1, vmax=1)
        plt.colorbar(label='e_v_momentum')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots',
                                 'e_v_momentum_plot.png'),
                    dpi=400)
        plt.close()
        plt.figure(figsize=figsize)
        # plt.title(f'fs divergence residual for {case_name_title}')
        plt.pcolor(X, Y, f_divergence, vmin=-1, vmax=1)
        plt.colorbar(label='f_divergence')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots',
                                 'f_divergence_plot.png'),
                    dpi=400)
        plt.close()

        def curl_f(X, V):
            dfsx_y = dde.grad.jacobian(V, X, i=3, j=1)
            dfsy_x = dde.grad.jacobian(V, X, i=4, j=0)
            return [dfsy_x - dfsx_y]

        e = model.predict(z, operator=curl_f)
        f_curl = e[0]

        data_dict.update({"curlf": f_curl})
        scipy.io.savemat(f"{case_name}/results.mat", data_dict)

        f_curl[no_data_index] = f_curl[no_data_index] * 0

        f_curl = f_curl.reshape(Nx, Ny).T

        plt.figure(figsize=figsize)
        # plt.title(f'curl fs for {case_name_title}')
        plt.pcolor(X, Y, f_curl)
        plt.colorbar(label='f_curl')
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots', 'f_curl_plot.png'),
                    dpi=400)
        plt.close()

        plt.figure(figsize=figsize)
        # plt.title(f'curl fs for {case_name_title}')
        plt.pcolor(X, Y, f_curl, vmin=-6.13125, vmax=6.26875)
        plt.colorbar(label=r"$\nabla \times \mathbf{f}$")
        plt.xlabel('x/c')
        plt.ylabel('y/c')
        plt.tight_layout()
        plt.savefig(os.path.join(f'{case_name}', 'plots',
                                 'f_curl_plot_rescaled.png'),
                    dpi=400)
        plt.close()