Beispiel #1
0
def test_get_internals():
    parametric_circle = lambda x1, x2, t: [diff(x1, t) - x2, diff(x2, t) + x1]

    init_vals_pc = [
        IVP(t_0=0.0, u_0=0.0),
        IVP(t_0=0.0, u_0=1.0),
    ]

    solver = Solver1D(
        ode_system=parametric_circle,
        conditions=init_vals_pc,
        t_min=0.0,
        t_max=2 * np.pi,
    )

    solver.fit(max_epochs=1)
    internals = solver.get_internals()
    assert isinstance(internals, dict)
    internals = solver.get_internals(return_type='list')
    assert isinstance(internals, dict)
    internals = solver.get_internals(return_type='dict')
    assert isinstance(internals, dict)
    internals = solver.get_internals(['generator', 'n_batches'], return_type='dict')
    assert isinstance(internals, dict)
    internals = solver.get_internals(['generator', 'n_batches'], return_type='list')
    assert isinstance(internals, list)
    internals = solver.get_internals('train_generator')
    assert isinstance(internals, BaseGenerator)
Beispiel #2
0
def test_monitor():

    laplace = lambda u, x, y: diff(u, x, order=2) + diff(u, y, order=2)
    bc = DirichletBVP2D(x_min=0,
                        x_min_val=lambda y: torch.sin(np.pi * y),
                        x_max=1,
                        x_max_val=lambda y: 0,
                        y_min=0,
                        y_min_val=lambda x: 0,
                        y_max=1,
                        y_max_val=lambda x: 0)

    net = FCNN(n_input_units=2, hidden_units=(32, 32))
    solution_neural_net_laplace, _ = solve2D(
        pde=laplace,
        condition=bc,
        xy_min=(0, 0),
        xy_max=(1, 1),
        net=net,
        max_epochs=3,
        train_generator=Generator2D((32, 32), (0, 0), (1, 1),
                                    method='equally-spaced-noisy'),
        batch_size=64,
        monitor=Monitor2D(check_every=1, xy_min=(0, 0), xy_max=(1, 1)))
    print('Monitor test passed.')
Beispiel #3
0
def test_laplace():

    laplace = lambda u, x, y: diff(u, x, order=2) + diff(u, y, order=2)
    bc = DirichletBVP2D(x_min=0,
                        x_min_val=lambda y: torch.sin(np.pi * y),
                        x_max=1,
                        x_max_val=lambda y: 0,
                        y_min=0,
                        y_min_val=lambda x: 0,
                        y_max=1,
                        y_max_val=lambda x: 0)

    net = FCNN(n_input_units=2, hidden_units=(32, 32))
    solution_neural_net_laplace, _ = solve2D(pde=laplace,
                                             condition=bc,
                                             xy_min=(0, 0),
                                             xy_max=(1, 1),
                                             net=net,
                                             max_epochs=300,
                                             train_generator=Generator2D(
                                                 (32, 32), (0, 0), (1, 1),
                                                 method='equally-spaced-noisy',
                                                 xy_noise_std=(0.01, 0.01)),
                                             batch_size=64)
    solution_analytical_laplace = lambda x, y: np.sin(np.pi * y) * np.sinh(
        np.pi * (1 - x)) / np.sinh(np.pi)

    xs, ys = np.linspace(0, 1, 101), np.linspace(0, 1, 101)
    xx, yy = np.meshgrid(xs, ys)
    sol_net = solution_neural_net_laplace(xx, yy, as_type='np')
    sol_ana = solution_analytical_laplace(xx, yy)
    assert isclose(sol_net, sol_ana, atol=0.01).all()
    print('Laplace test passed.')
Beispiel #4
0
def test_lotka_volterra():
    alpha, beta, delta, gamma = 1, 1, 1, 1
    lotka_volterra = lambda x, y, t : [diff(x, t) - (alpha*x  - beta*x*y),
                                       diff(y, t) - (delta*x*y - gamma*y)]
    init_vals_lv = [
        IVP(t_0=0.0, x_0=1.5),
        IVP(t_0=0.0, x_0=1.0)
    ]
    nets_lv = [
        FCNN(hidden_units=(32, 32), actv=SinActv),
        FCNN(hidden_units=(32, 32), actv=SinActv),
    ]
    solution_lv, _ = solve_system(ode_system=lotka_volterra, conditions=init_vals_lv,
                                  t_min=0.0, t_max=12, nets=nets_lv, max_epochs=12000,
                                  monitor=Monitor(t_min=0.0, t_max=12, check_every=100))
    ts = np.linspace(0, 12, 100)
    prey_net, pred_net = solution_lv(ts, as_type='np')

    def dPdt(P, t):
        return [P[0]*alpha - beta*P[0]*P[1], delta*P[0]*P[1] - gamma*P[1]]
    P0 = [1.5, 1.0]
    Ps = odeint(dPdt, P0, ts)
    prey_num = Ps[:,0]
    pred_num = Ps[:,1]
    assert isclose(prey_net, prey_num, atol=0.1).all()
    assert isclose(pred_net, pred_num, atol=0.1).all()
    print('Lotka Volterra test passed.')
Beispiel #5
0
def spherical_curl(u_r, u_theta, u_phi, r, theta, phi):
    r"""Derives and evaluates the spherical curl of a spherical vector field :math:`u`

    :param u_r: :math:`r`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_r: `torch.Tensor`
    :param u_theta: :math:`\theta`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_theta: `torch.Tensor`
    :param u_phi: :math:`\phi`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_phi: `torch.Tensor`
    :param r: a vector of :math:`r`-coordinate values, must have shape (n_samples, 1)
    :type r: `torch.Tensor`
    :param theta: a vector of :math:`\theta`-coordinate values, must have shape (n_samples, 1)
    :type theta: `torch.Tensor`
    :param phi: a vector of :math:`\phi`-coordinate values, must have shape (n_samples, 1)
    :type phi: `torch.Tensor`
    :return: :math:`r`, :math:`\theta`, and :math:`\phi` components of the curl, each with shape (n_samples, 1)
    :rtype: tuple[`torch.Tensor`]
    """

    d_r = lambda u: diff(u, r)
    d_theta = lambda u: diff(u, theta)
    d_phi = lambda u: diff(u, phi)

    curl_r = (d_theta(u_phi * sin(theta)) - d_phi(u_theta)) / (r * sin(theta))
    curl_theta = (d_phi(u_r) / sin(theta) - d_r(u_phi * r)) / r
    curl_phi = (d_r(u_theta * r) - d_theta(u_r)) / r

    return curl_r, curl_theta, curl_phi
Beispiel #6
0
def test_laplace():
    laplace = lambda u, x, y: diff(u, x, order=2) + diff(u, y, order=2)
    bc = DirichletBVP2D(x_min=0,
                        x_min_val=lambda y: torch.sin(np.pi * y),
                        x_max=1,
                        x_max_val=lambda y: 0,
                        y_min=0,
                        y_min_val=lambda x: 0,
                        y_max=1,
                        y_max_val=lambda x: 0)

    net = FCNN(n_input_units=2, hidden_units=(32, 32))
    solution_neural_net_laplace, loss_history = solve2D(
        pde=laplace,
        condition=bc,
        xy_min=(0, 0),
        xy_max=(1, 1),
        net=net,
        max_epochs=3,
        train_generator=Generator2D((32, 32), (0, 0), (1, 1),
                                    method='equally-spaced-noisy',
                                    xy_noise_std=(0.01, 0.01)),
        batch_size=64)
    assert isinstance(solution_neural_net_laplace, Solution2D)
    assert isinstance(loss_history, dict)
    keys = ['train_loss', 'valid_loss']
    for key in keys:
        assert key in loss_history
        assert isinstance(loss_history[key], list)
    assert len(loss_history[keys[0]]) == len(loss_history[keys[1]])
def laplacian_spherical(u, r, theta, phi):
    """a helper function that computes the Laplacian in spherical coordinates
    """
    r_component = diff(u * r, r, order=2) / r
    theta_component = diff(torch.sin(theta) * diff(u, theta),
                           theta) / (r**2 * torch.sin(theta))
    phi_component = diff(u, phi, order=2) / (r**2 * torch.sin(theta)**2)
    return r_component + theta_component + phi_component
Beispiel #8
0
def test_legacy_signature():
    u, t = get_data(flatten_u=False, flatten_t=False)
    with pytest.warns(FutureWarning):
        diff(x=u, t=t)
    with pytest.warns(FutureWarning):
        safe_diff(x=u, t=t)
    with pytest.warns(FutureWarning):
        unsafe_diff(x=u, t=t)
Beispiel #9
0
def test_higher_order_derivatives():
    u, t = get_data(flatten_u=False, flatten_t=False, f=lambda x: x**2)
    assert torch.isclose(diff(u, t), t * 2).all()
    assert torch.isclose(diff(u, t, order=2), 2 * torch.ones_like(t)).all()
    for order in range(3, 10):
        assert torch.isclose(diff(u, t, order=order),
                             torch.zeros_like(t)).all()

    u, t = get_data(flatten_u=False, flatten_t=False, f=torch.exp)
    for order in range(1, 10):
        assert torch.isclose(diff(u, t, order=order), u).all()
def test_ibvp_ode():
    x0, x1 = random.random(), random.random() + 1
    u0, u0_prime = random.random(), random.random()
    u1, u1_prime = random.random(), random.random()
    net = FCNN(1, 1)
    # test Dirichlet-Dirichlet
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_val=u0,
                                 x_max_val=u1)
    x = x0 * ones
    assert all_close(condition.enforce(net, x),
                     u0), 'left Dirichlet BC not satisfied'
    x = x1 * ones
    assert all_close(condition.enforce(net, x),
                     u1), 'right Dirichlet BC not satisfied'
    # test Dirichlet-Neumann
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_val=u0,
                                 x_max_prime=u1_prime)
    x = x0 * ones
    assert all_close(condition.enforce(net, x),
                     u0), 'left Dirichlet BC not satisfied'
    x = x1 * ones
    assert all_close(diff(condition.enforce(net, x), x),
                     u1_prime), 'right Neumann BC not satisfied'
    # test Neumann-Dirichlet
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_prime=u0_prime,
                                 x_max_val=u1)
    x = x0 * ones
    assert all_close(diff(condition.enforce(net, x), x),
                     u0_prime), 'left Neumann BC not satisfied'
    x = x1 * ones
    assert all_close(condition.enforce(net, x),
                     u1), 'right Dirichlet BC not satisfied'
    # test Neumann-Neumann
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_prime=u0_prime,
                                 x_max_prime=u1_prime)
    x = x0 * ones
    assert all_close(diff(condition.enforce(net, x), x),
                     u0_prime), 'left Neumann BC not satisfied'
    x = x1 * ones
    assert all_close(diff(condition.enforce(net, x), x),
                     u1_prime), 'right Neumann BC not satisfied'
Beispiel #11
0
def test_double_ended_bvp_1d(x0, x1, u00, u01, u10, u11, ones, net11):
    u0, u0_prime = u00, u01
    u1, u1_prime = u10, u11
    # test Dirichlet-Dirichlet
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_val=u0,
                                 x_max_val=u1)
    x = x0 * ones
    assert all_close(condition.enforce(net11, x),
                     u0), 'left Dirichlet BC not satisfied'
    x = x1 * ones
    assert all_close(condition.enforce(net11, x),
                     u1), 'right Dirichlet BC not satisfied'
    # test Dirichlet-Neumann
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_val=u0,
                                 x_max_prime=u1_prime)
    x = x0 * ones
    assert all_close(condition.enforce(net11, x),
                     u0), 'left Dirichlet BC not satisfied'
    x = x1 * ones
    assert all_close(diff(condition.enforce(net11, x), x),
                     u1_prime), 'right Neumann BC not satisfied'
    # test Neumann-Dirichlet
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_prime=u0_prime,
                                 x_max_val=u1)
    x = x0 * ones
    assert all_close(diff(condition.enforce(net11, x), x),
                     u0_prime), 'left Neumann BC not satisfied'
    x = x1 * ones
    assert all_close(condition.enforce(net11, x),
                     u1), 'right Dirichlet BC not satisfied'
    # test Neumann-Neumann
    condition = DoubleEndedBVP1D(x_min=x0,
                                 x_max=x1,
                                 x_min_prime=u0_prime,
                                 x_max_prime=u1_prime)
    x = x0 * ones
    assert all_close(diff(condition.enforce(net11, x), x),
                     u0_prime), 'left Neumann BC not satisfied'
    x = x1 * ones
    assert all_close(diff(condition.enforce(net11, x), x),
                     u1_prime), 'right Neumann BC not satisfied'
Beispiel #12
0
def test_monitor():
    exponential = lambda x, t: diff(x, t) - x
    init_val_ex = IVP(t_0=0.0, x_0=1.0)
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0,
                           max_epochs=3,
                           monitor=Monitor(t_min=0.0, t_max=2.0, check_every=1))
    print('Monitor test passed.')
Beispiel #13
0
def spherical_grad(u, r, theta, phi):
    r"""Derives and evaluates the spherical gradient of a spherical scalar field :math:`u`

    :param u: a scalar field :math:`u`, must have shape (n_samples, 1)
    :type u: `torch.Tensor`
    :param r: a vector of :math:`r`-coordinate values, must have shape (n_samples, 1)
    :type r: `torch.Tensor`
    :param theta: a vector of :math:`\theta`-coordinate values, must have shape (n_samples, 1)
    :type theta: `torch.Tensor`
    :param phi: a vector of :math:`\phi`-coordinate values, must have shape (n_samples, 1)
    :type phi: `torch.Tensor`
    :return: :math:`r`, :math:`\theta`, and :math:`\phi` components of the gradient, each with shape (n_samples, 1)
    :rtype: tuple[`torch.Tensor`]
    """
    grad_r = diff(u, r)
    grad_theta = diff(u, theta) / r
    grad_phi = diff(u, phi) / (r * sin(theta))
    return grad_r, grad_theta, grad_phi
Beispiel #14
0
def test_train_generator():
    laplace = lambda u, x, y: diff(u, x, order=2) + diff(u, y, order=2)
    bc = DirichletBVP2D(
        x_min=0, x_min_val=lambda y: torch.sin(np.pi * y),
        x_max=1, x_max_val=lambda y: 0,
        y_min=0, y_min_val=lambda x: 0,
        y_max=1, y_max_val=lambda x: 0
    )

    net = FCNN(n_input_units=2, hidden_units=(32, 32))
    solution_neural_net_laplace, _ = solve2D(
        pde=laplace, condition=bc, xy_min=(0, 0), xy_max=(1, 1),
        net=net, max_epochs=3,
        train_generator=Generator2D((32, 32), (0, 0), (1, 1), method='equally-spaced-noisy'),
        batch_size=64,
        monitor=Monitor2D(check_every=1, xy_min=(0, 0), xy_max=(1, 1))
    )

    train_gen = Generator2D((32, 32), (0, 0), (1, 1), method='equally-spaced')
    solution_neural_net_laplace, _ = solve2D(
        pde=laplace, condition=bc, xy_min=(0, 0), xy_max=(1, 1),
        net=net, max_epochs=3, train_generator=train_gen, batch_size=64
    )
    train_gen = Generator2D((32, 32), (0, 0), (1, 1), method='equally-spaced-noisy')
    solution_neural_net_laplace, _ = solve2D(
        pde=laplace, condition=bc, xy_min=(0, 0), xy_max=(1, 1),
        net=net, max_epochs=3, train_generator=train_gen, batch_size=64
    )

    with raises(ValueError):
        train_gen = Generator2D((32, 32), (0, 0), (1, 1), method='magic')

    valid_gen = Generator2D((32, 32), (0, 0), (1, 1), method='equally-spaced-noisy')
    train_gen = Generator2D((32, 32), (0, 0), (1, 1), method='equally-spaced')
    solution_neural_net_laplace, _ = solve2D(
        pde=laplace, condition=bc,
        net=net, max_epochs=3, train_generator=train_gen, valid_generator=valid_gen, batch_size=64
    )

    with raises(RuntimeError):
        solution_neural_net_laplace, _ = solve2D(
            pde=laplace, condition=bc,
            net=net, max_epochs=3, batch_size=64
        )
Beispiel #15
0
def test_ivp(x0, y0, y1, ones, net11):
    x = x0 * ones
    cond = IVP(x0, y0)
    y = cond.enforce(net11, x)
    assert torch.isclose(y, y0 * ones).all(), "y(x_0) != y_0"

    cond = IVP(x0, y0, y1)
    y = cond.enforce(net11, x)
    assert all_close(y, y0), "y(x_0) != y_0"
    assert all_close(diff(y, x), y1), "y'(x_0) != y'_0"
Beispiel #16
0
def test_train_generator():
    laplace = lambda u, x, y: diff(u, x, order=2) + diff(u, y, order=2)
    bc = DirichletBVP2D(x_min=0,
                        x_min_val=lambda y: torch.sin(np.pi * y),
                        x_max=1,
                        x_max_val=lambda y: 0,
                        y_min=0,
                        y_min_val=lambda x: 0,
                        y_max=1,
                        y_max_val=lambda x: 0)

    net = FCNN(n_input_units=2, hidden_units=(32, 32))

    with pytest.raises(ValueError), pytest.warns(FutureWarning):
        solution_neural_net_laplace, _ = solve2D(pde=laplace,
                                                 condition=bc,
                                                 net=net,
                                                 max_epochs=3,
                                                 batch_size=64)
Beispiel #17
0
def test_ode_system():
    parametric_circle = lambda u1, u2, t: [diff(u1, t) - u2, diff(u2, t) + u1]
    init_vals_pc = [IVP(t_0=0.0, u_0=0.0), IVP(t_0=0.0, u_0=1.0)]

    solution_pc, loss_history = solve_system(
        ode_system=parametric_circle,
        conditions=init_vals_pc,
        t_min=0.0,
        t_max=2 * np.pi,
        max_epochs=10,
    )

    assert isinstance(solution_pc, Solution)
    assert isinstance(loss_history, dict)
    keys = ['train_loss', 'valid_loss']
    for key in keys:
        assert key in loss_history
        assert isinstance(loss_history[key], list)
    assert len(loss_history[keys[0]]) == len(loss_history[keys[1]])
Beispiel #18
0
def test_monitor():
    exponential = lambda u, t: diff(u, t) - u
    init_val_ex = IVP(t_0=0.0, u_0=1.0)
    solution_ex, _ = solve(ode=exponential,
                           condition=init_val_ex,
                           t_min=0.0,
                           t_max=2.0,
                           max_epochs=3,
                           monitor=Monitor(t_min=0.0, t_max=2.0,
                                           check_every=1))
Beispiel #19
0
def test_ode_ivp():
    oscillator = lambda x, t: diff(x, t, order=2) + x
    init_val_ho = IVP(t_0=0.0, x_0=0.0, x_0_prime=1.0)
    solution_ho, _ = solve(ode=oscillator, condition=init_val_ho,
                           max_epochs=3000,
                           t_min=0.0, t_max=2*np.pi)
    ts = np.linspace(0, 2*np.pi, 100)
    x_net = solution_ho(ts, as_type='np')
    x_ana = np.sin(ts)
    assert isclose(x_net, x_ana, atol=0.1).all()
    print('IVP basic test passed.')
Beispiel #20
0
def test_ode_bvp():
    oscillator = lambda x, t: diff(x, t, order=2) + x
    bound_val_ho = DirichletBVP(t_0=0.0, x_0=0.0, t_1=1.5*np.pi, x_1=-1.0)
    solution_ho, _ = solve(ode=oscillator, condition=bound_val_ho,
                           max_epochs=3000,
                           t_min=0.0, t_max=1.5*np.pi)
    ts = np.linspace(0, 1.5*np.pi, 100)
    x_net = solution_ho(ts, as_type='np')
    x_ana = np.sin(ts)
    assert isclose(x_net, x_ana, atol=0.1).all()
    print('BVP basic test passed.')
Beispiel #21
0
def test_ode_system():

    parametric_circle = lambda x1, x2, t : [diff(x1, t) - x2,
                                            diff(x2, t) + x1]
    init_vals_pc = [
        IVP(t_0=0.0, x_0=0.0),
        IVP(t_0=0.0, x_0=1.0)
    ]

    solution_pc, _ = solve_system(ode_system=parametric_circle,
                                  conditions=init_vals_pc,
                                  t_min=0.0, t_max=2*np.pi,
                                  max_epochs=5000,)

    ts = np.linspace(0, 2*np.pi, 100)
    x1_net, x2_net = solution_pc(ts, as_type='np')
    x1_ana, x2_ana = np.sin(ts), np.cos(ts)
    assert isclose(x1_net, x1_ana, atol=0.1).all()
    assert isclose(x2_net, x2_ana, atol=0.1).all()
    print('solve_system basic test passed.')
Beispiel #22
0
def spherical_vector_laplacian(u_r, u_theta, u_phi, r, theta, phi):
    r"""Derives and evaluates the spherical laplacian of a spherical vector field :math:`u`

    :param u_r: :math:`r`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_r: `torch.Tensor`
    :param u_theta: :math:`\theta`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_theta: `torch.Tensor`
    :param u_phi: :math:`\phi`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_phi: `torch.Tensor`
    :param r: a vector of :math:`r`-coordinate values, must have shape (n_samples, 1)
    :type r: `torch.Tensor`
    :param theta: a vector of :math:`\theta`-coordinate values, must have shape (n_samples, 1)
    :type theta: `torch.Tensor`
    :param phi: a vector of :math:`\phi`-coordinate values, must have shape (n_samples, 1)
    :type phi: `torch.Tensor`
    :return: the laplacian evaluated at :math:`(r, \theta, \phi)`, with shape (n_samples, 1)
    :rtype: `torch.Tensor`
    """
    d_theta = lambda u: diff(u, theta)
    d_phi = lambda u: diff(u, phi)
    scalar_lap = lambda u: spherical_laplacian(u, r, theta, phi)

    lap_r = \
        scalar_lap(u_r) \
        - 2 * u_r / r ** 2 \
        - 2 * d_theta(u_theta * sin(theta)) / (r ** 2 * sin(theta)) \
        - 2 * d_phi(u_phi) / (r ** 2 * sin(theta))

    lap_theta = \
        scalar_lap(u_theta) \
        - u_theta / (r ** 2 * sin(theta) ** 2) \
        + 2 * d_theta(u_r) / r ** 2 \
        - 2 * cos(theta) * d_phi(u_phi) / (r ** 2 * sin(theta) ** 2)

    lap_phi = \
        scalar_lap(u_phi) \
        - u_phi / (r ** 2 * sin(theta) ** 2) \
        + 2 * d_phi(u_r) / (r ** 2 * sin(theta)) \
        + 2 * cos(theta) * d_phi(u_theta) / (r ** 2 * sin(theta) ** 2)

    return lap_r, lap_theta, lap_phi
Beispiel #23
0
def test_ivp():
    x = x0 * ones
    net = FCNN(1, 1)

    cond = IVP(x0, y0)
    y = cond.enforce(net, x)
    assert torch.isclose(y, y0 * ones).all(), "y(x_0) != y_0"

    cond = IVP(x0, y0, y1)
    y = cond.enforce(net, x)
    assert all_close(y, y0), "y(x_0) != y_0"
    assert all_close(diff(y, x), y1), "y'(x_0) != y'_0"
Beispiel #24
0
def test_heat():

    k, L, T = 0.3, 2, 3
    heat = lambda u, x, t: diff(u, t) - k * diff(u, x, order=2)

    ibvp = IBVP1D(x_min=0,
                  x_min_val=lambda t: 0,
                  x_max=L,
                  x_max_val=lambda t: 0,
                  t_min=0,
                  t_min_val=lambda x: torch.sin(np.pi * x / L))
    net = FCNN(n_input_units=2, hidden_units=(32, 32))

    def mse(u, x, y):
        true_u = torch.sin(np.pi * y) * torch.sinh(np.pi *
                                                   (1 - x)) / np.sinh(np.pi)
        return torch.mean((u - true_u)**2)

    solution_neural_net_heat, _ = solve2D(pde=heat,
                                          condition=ibvp,
                                          xy_min=(0, 0),
                                          xy_max=(L, T),
                                          net=net,
                                          max_epochs=300,
                                          train_generator=Generator2D(
                                              (32, 32), (0, 0), (L, T),
                                              method='equally-spaced-noisy'),
                                          batch_size=64,
                                          metrics={'mse': mse})
    solution_analytical_heat = lambda x, t: np.sin(np.pi * x / L) * np.exp(
        -k * np.pi**2 * t / L**2)

    xs = np.linspace(0, L, 101)
    ts = np.linspace(0, T, 101)
    xx, tt = np.meshgrid(xs, ts)
    make_animation(solution_neural_net_heat, xs, ts)  # test animation
    sol_ana = solution_analytical_heat(xx, tt)
    sol_net = solution_neural_net_heat(xx, tt, as_type='np')
    assert isclose(sol_net, sol_ana, atol=0.01).all()
    print('Heat test passed.')
Beispiel #25
0
def spherical_div(u_r, u_theta, u_phi, r, theta, phi):
    r"""Derives and evaluates the spherical divergence of a spherical vector field :math:`u`

    :param u_r: :math:`r`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_r: `torch.Tensor`
    :param u_theta: :math:`\theta`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_theta: `torch.Tensor`
    :param u_phi: :math:`\phi`-component of the vector field :math:`u`, must have shape (n_samples, 1)
    :type u_phi: `torch.Tensor`
    :param r: a vector of :math:`r`-coordinate values, must have shape (n_samples, 1)
    :type r: `torch.Tensor`
    :param theta: a vector of :math:`\theta`-coordinate values, must have shape (n_samples, 1)
    :type theta: `torch.Tensor`
    :param phi: a vector of :math:`\phi`-coordinate values, must have shape (n_samples, 1)
    :type phi: `torch.Tensor`
    :return: the divergence evaluated at :math:`(r, \theta, \phi)`, with shape (n_samples, 1)
    :rtype: `torch.Tensor`
    """
    div_r = diff(u_r * r**2, r) / r**2
    div_theta = diff(u_theta * sin(theta), theta) / (r * sin(theta))
    div_phi = diff(u_phi, phi) / (r * sin(theta))
    return div_r + div_theta + div_phi
Beispiel #26
0
def spherical_laplacian(u, r, theta, phi):
    r"""Derives and evaluates the spherical laplacian of a spherical scalar field :math:`u`

    :param u: a scalar field :math:`u`, must have shape (n_samples, 1)
    :type u: `torch.Tensor`
    :param r: a vector of :math:`r`-coordinate values, must have shape (n_samples, 1)
    :type r: `torch.Tensor`
    :param theta: a vector of :math:`\theta`-coordinate values, must have shape (n_samples, 1)
    :type theta: `torch.Tensor`
    :param phi: a vector of :math:`\phi`-coordinate values, must have shape (n_samples, 1)
    :type phi: `torch.Tensor`
    :return: the laplacian evaluated at :math:`(r, \theta, \phi)`, with shape (n_samples, 1)
    :rtype: `torch.Tensor`
    """
    d_r = lambda u: diff(u, r)
    d_theta = lambda u: diff(u, theta)
    d_phi = lambda u: diff(u, phi)

    lap_r = d_r(d_r(u) * r**2) / r**2
    lap_theta = d_theta(d_theta(u) * sin(theta)) / (r**2 * sin(theta))
    lap_phi = d_phi(d_phi(u)) / (r**2 * sin(theta)**2)
    return lap_r + lap_theta + lap_phi
Beispiel #27
0
def test_neumann_boundaries_2():

    k, L, T = 0.3, 2, 3
    heat = lambda u, x, t: diff(u, t) - k * diff(u, x, order=2)
    solution_analytical_heat = lambda x, t: np.sin(np.pi * x / L) * np.exp(
        -k * np.pi**2 * t / L**2)

    # Neumann on the left Dirichlet on the right
    ibvp = IBVP1D(
        x_min=0,
        x_min_prime=lambda t: np.pi / L * torch.exp(-k * np.pi**2 * t / L**2),
        x_max=L,
        x_max_val=lambda t: 0,
        t_min=0,
        t_min_val=lambda x: torch.sin(np.pi * x / L))

    net = FCNN(n_input_units=2, hidden_units=(32, 32))

    solution_neural_net_heat, _ = solve2D(pde=heat,
                                          condition=ibvp,
                                          xy_min=(0, 0),
                                          xy_max=(L, T),
                                          net=net,
                                          max_epochs=300,
                                          train_generator=Generator2D(
                                              (32, 32), (0, 0), (L, T),
                                              method='equally-spaced-noisy'),
                                          batch_size=64)

    xs = np.linspace(0, L, 101)
    ts = np.linspace(0, T, 101)
    xx, tt = np.meshgrid(xs, ts)
    make_animation(solution_neural_net_heat, xs, ts)  # test animation
    sol_ana = solution_analytical_heat(xx, tt)
    sol_net = solution_neural_net_heat(xx, tt, as_type='np')
    assert isclose(sol_net, sol_ana, atol=0.1).all()
    print('Neumann on the left Dirichlet on the right test passed.')
Beispiel #28
0
def test_ode():

    def mse(x, t):
        true_x = torch.sin(t)
        return torch.mean((x - true_x) ** 2)
    exponential = lambda x, t: diff(x, t) - x
    init_val_ex = IVP(t_0=0.0, x_0=1.0)
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0, shuffle=False,
                           max_epochs=2000, return_best=True, metrics={'mse': mse})
    ts = np.linspace(0, 2.0, 100)
    x_net = solution_ex(ts, as_type='np')
    x_ana = np.exp(ts)
    assert isclose(x_net, x_ana, atol=0.1).all()
    print('solve basic test passed.')
Beispiel #29
0
def test_ode():
    def mse(u, t):
        true_u = torch.sin(t)
        return torch.mean((u - true_u) ** 2)

    exponential = lambda u, t: diff(u, t) - u
    init_val_ex = IVP(t_0=0.0, u_0=1.0)
    solution_ex, loss_history = solve(ode=exponential, condition=init_val_ex,
                                      t_min=0.0, t_max=2.0, shuffle=False,
                                      max_epochs=10, return_best=True, metrics={'mse': mse})

    assert isinstance(solution_ex, Solution1D)
    assert isinstance(loss_history, dict)
    keys = ['train_loss', 'valid_loss']
    for key in keys:
        assert key in loss_history
        assert isinstance(loss_history[key], list)
    assert len(loss_history[keys[0]]) == len(loss_history[keys[1]])
Beispiel #30
0
def test_train_generator():
    exponential = lambda x, t: diff(x, t) - x
    init_val_ex = IVP(t_0=0.0, x_0=1.0)

    train_gen = Generator1D(size=32, t_min=0.0, t_max=2.0, method='uniform')
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=0.0, t_max=2.0, method='equally-spaced')
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=0.0, t_max=2.0, method='equally-spaced-noisy')
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=0.0, t_max=2.0, method='equally-spaced-noisy', noise_std=0.01)
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.0, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=np.log10(0.1), t_max=np.log10(2.0), method='log-spaced')
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.1, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=np.log10(0.1), t_max=np.log10(2.0), method='log-spaced-noisy')
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.1, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)
    train_gen = Generator1D(size=32, t_min=np.log10(0.1), t_max=np.log10(2.0), method='log-spaced-noisy', noise_std=0.01)
    solution_ex, _ = solve(ode=exponential, condition=init_val_ex,
                           t_min=0.1, t_max=2.0,
                           train_generator=train_gen,
                           max_epochs=3)

    with raises(ValueError):
        train_gen = Generator1D(size=32, t_min=0.0, t_max=2.0, method='magic')
    print('ExampleGenerator test passed.')