示例#1
0
def test_callback_tracker():
    """ test trackers that support a callback """
    data = []

    def store_mean_data(state):
        data.append(state.average)

    def get_mean_data(state):
        return state.average

    grid = UnitGrid([4, 4])
    state = ScalarField.random_uniform(grid, 0.2, 0.3)
    pde = DiffusionPDE()
    data_tracker = trackers.DataTracker(get_mean_data, interval=0.1)
    callback_tracker = trackers.CallbackTracker(store_mean_data, interval=0.1)
    tracker_list = [data_tracker, callback_tracker]
    pde.solve(state,
              t_range=0.5,
              dt=0.005,
              tracker=tracker_list,
              backend="numpy")

    np.testing.assert_array_equal(data, data_tracker.data)

    data = []

    def store_time(state, t):
        data.append(t)

    def get_time(state, t):
        return t

    grid = UnitGrid([4, 4])
    state = ScalarField.random_uniform(grid, 0.2, 0.3)
    pde = DiffusionPDE()
    data_tracker = trackers.DataTracker(get_time, interval=0.1)
    tracker_list = [
        trackers.CallbackTracker(store_time, interval=0.1), data_tracker
    ]
    pde.solve(state,
              t_range=0.5,
              dt=0.005,
              tracker=tracker_list,
              backend="numpy")

    ts = np.arange(0, 0.55, 0.1)
    np.testing.assert_allclose(data, ts, atol=1e-2)
    np.testing.assert_allclose(data_tracker.data, ts, atol=1e-2)
def test_interactive_collection_plotting():
    """ test the interactive plotting """
    grid = UnitGrid([3, 3])
    sf = ScalarField.random_uniform(grid, 0.1, 0.9)
    vf = VectorField.random_uniform(grid, 0.1, 0.9)
    field = FieldCollection([sf, vf])
    field.plot_interactive(viewer_args={"show": False, "close": True})
示例#3
0
def test_simulation_persistence(compression, tmp_path):
    """test whether a tracker can accurately store information about
    simulation"""
    path = tmp_path / "test_simulation_persistence.hdf5"
    storage = FileStorage(path, compression=compression)

    # write some simulation data
    pde = DiffusionPDE()
    grid = UnitGrid([16, 16])  # generate grid
    state = ScalarField.random_uniform(grid, 0.2, 0.3)
    pde.solve(state,
              t_range=0.11,
              dt=0.001,
              tracker=storage.tracker(interval=0.05))
    storage.close()

    # read the data
    storage = FileStorage(path)
    np.testing.assert_almost_equal(storage.times, [0, 0.05, 0.1])
    data = np.array(storage.data)
    assert data.shape == (3, ) + state.data.shape
    grid_res = storage.grid
    assert grid == grid_res
    grid_res = storage.grid
    assert grid == grid_res
示例#4
0
def test_runtime_tracker():
    """ test the RuntimeTracker """
    s = ScalarField.random_uniform(UnitGrid([128]))
    tracker = trackers.RuntimeTracker("0:01")
    sol = ExplicitSolver(DiffusionPDE())
    con = Controller(sol, t_range=1e4, tracker=["progress", tracker])
    con.run(s, dt=1e-3)
示例#5
0
def test_conservative_laplace_polar():
    """test and compare the two implementation of the laplace operator"""
    grid = PolarSymGrid(1.5, 8)
    f = ScalarField.random_uniform(grid)

    res = f.laplace("auto_periodic_neumann")
    np.testing.assert_allclose(res.integral, 0, atol=1e-12)
示例#6
0
def test_trackers():
    """ test whether simple trackers can be used """
    times = []

    def store_time(state, t):
        times.append(t)

    def get_data(state):
        return {"integral": state.integral}

    devnull = open(os.devnull, "w")
    data = trackers.DataTracker(get_data, interval=0.1)
    tracker_list = [
        trackers.PrintTracker(interval=0.1, stream=devnull),
        trackers.CallbackTracker(store_time, interval=0.1),
        None,  # should be ignored
        data,
    ]
    if module_available("matplotlib"):
        tracker_list.append(trackers.PlotTracker(interval=0.1, show=False))

    grid = UnitGrid([16, 16])
    state = ScalarField.random_uniform(grid, 0.2, 0.3)
    pde = DiffusionPDE()
    pde.solve(state, t_range=1, dt=0.005, tracker=tracker_list)

    devnull.close()

    assert times == data.times
    if module_available("pandas"):
        df = data.dataframe
        np.testing.assert_allclose(df["time"], times)
        np.testing.assert_allclose(df["integral"], state.integral)
示例#7
0
def test_diffusion_cached():
    """test some caching of rhs of the simple diffusion model"""
    grid = UnitGrid([8])
    c0 = ScalarField.random_uniform(grid)

    # first run without cache
    eq1 = DiffusionPDE(diffusivity=1)
    eq1.cache_rhs = False
    c1a = eq1.solve(c0, t_range=1, dt=0.1, backend="numba", tracker=None)

    eq1.diffusivity = 0.1
    c1b = eq1.solve(c1a, t_range=1, dt=0.1, backend="numba", tracker=None)

    # then run with cache
    eq2 = DiffusionPDE(diffusivity=1)
    eq2.cache_rhs = True
    c2a = eq2.solve(c0, t_range=1, dt=0.1, backend="numba", tracker=None)

    eq2.diffusivity = 0.1
    c2b = eq2.solve(c2a, t_range=1, dt=0.1, backend="numba", tracker=None)

    eq2._cache = {}  # clear cache
    c2c = eq2.solve(c2a, t_range=1, dt=0.1, backend="numba", tracker=None)

    np.testing.assert_allclose(c1a.data, c2a.data)
    assert not np.allclose(c1b.data, c2b.data)
    np.testing.assert_allclose(c1b.data, c2c.data)
示例#8
0
def test_laplace_1d():
    """test the implementation of the laplace operator"""
    for periodic in [True, False]:
        bcs = _get_random_grid_bcs(1, periodic=periodic)
        field = ScalarField.random_uniform(bcs.grid)
        l1 = field.laplace(bcs, backend="scipy")
        l2 = field.laplace(bcs, backend="numba")
        np.testing.assert_allclose(l1.data, l2.data)
示例#9
0
def test_steady_state_tracker():
    """ test the SteadyStateTracker """
    storage = MemoryStorage()
    c0 = ScalarField.random_uniform(UnitGrid([5]))
    pde = DiffusionPDE()
    tracker = trackers.SteadyStateTracker(atol=1e-2, rtol=1e-2, progress=True)
    pde.solve(c0, 1e3, dt=0.1, tracker=[tracker, storage.tracker(interval=1e2)])
    assert len(storage) < 9  # finished early
示例#10
0
def test_consistency_tracker():
    """ test the ConsistencyTracker """
    s = ScalarField.random_uniform(UnitGrid([128]))
    sol = ExplicitSolver(DiffusionPDE(1e3))
    con = Controller(sol, t_range=1e5, tracker=["consistency"])
    with np.errstate(all="ignore"):
        con.run(s, dt=1)
    assert con.info["t_final"] < con.info["t_end"]
def test_conservative_laplace():
    """ test and compare the two implementation of the laplace operator """
    grid = PolarGrid(1.5, 8)
    f = ScalarField.random_uniform(grid)

    bcs = grid.get_boundary_conditions("natural")
    lap = ops.make_laplace(bcs)
    np.testing.assert_allclose(f.apply(lap).integral, 0, atol=1e-12)
示例#12
0
def main(equation: str = "cahn-hilliard",
         t_range: float = 100,
         size: int = 32):
    """main routine testing the performance

    Args:
        equation (str): Chooses the equation to consider
        t_range (float): Sets the total duration that should be solved for
        size (int): The number of grid points along each axis
    """
    print("Reports duration in seconds (smaller is better)\n")

    # determine grid and initial state
    grid = UnitGrid([size, size], periodic=False)
    field = ScalarField.random_uniform(grid)
    print(f"GRID: {grid}")

    # determine the equation to solve
    if equation == "diffusion":
        eq = DiffusionPDE()
    elif equation == "cahn-hilliard":
        eq = CahnHilliardPDE()
    else:
        raise ValueError(f"Undefined equation `{equation}`")
    print(f"EQUATION: ∂c/∂t = {eq.expression}")

    print("\nSOLVER PERFORMANCE:")

    expected = eq.solve(field, t_range=t_range, dt=1e-5, tracker=None)

    solvers = {
        "Euler, fixed":
        (1e-3, ExplicitSolver(eq, scheme="euler", adaptive=False)),
        "Euler, adaptive":
        (1e-3, ExplicitSolver(eq, scheme="euler", adaptive=True)),
        "Runge-Kutta, fixed":
        (1e-3, ExplicitSolver(eq, scheme="rk", adaptive=False)),
        "Runge-Kutta, adaptive": (1e-3,
                                  ExplicitSolver(eq,
                                                 scheme="rk",
                                                 adaptive=True)),
        "implicit": (1e-3, ImplicitSolver(eq)),
        "scipy": (None, ScipySolver(eq)),
    }

    for name, (dt, solver) in solvers.items():

        solver.backend = "numba"
        controller = Controller(solver, t_range=t_range, tracker=None)
        result = controller.run(field, dt=dt)

        # call once to pre-compile and test result
        if np.allclose(result.data, expected.data, atol=1e-2):
            # report the duration
            print(f"{name:>21s}: {controller.info['profiler']['solver']:.3g}")
        else:
            # report the mismatch
            print(f"{name:>21s}: MISMATCH")
示例#13
0
def test_writing_to_storage(tmp_path):
    """test whether data is written to storage"""
    state = ScalarField.random_uniform(UnitGrid([3]))
    pde = DiffusionPDE()
    path = tmp_path / "test_writing_to_storage.hdf5"
    data = FileStorage(filename=path)
    pde.solve(state, t_range=1.1, dt=0.1, tracker=[data.tracker(0.5)])

    assert len(data) == 3
示例#14
0
def test_simple_diffusion_flux_right():
    """test a simple diffusion equation with flux boundary on the right"""
    grid = CartesianGrid([[0, 1]], [16])
    c = ScalarField.random_uniform(grid, 0, 1)
    b_l = {"type": "value", "value": 0}
    b_r = {"type": "derivative", "value": 3}
    pde = DiffusionPDE(bc=[b_l, b_r])
    sol = pde.solve(c, t_range=5, dt=0.001, tracker=None)
    np.testing.assert_allclose(sol.data, 3 * grid.axes_coords[0], rtol=5e-3)
def test_unsupported_stochastic_solvers():
    """test some solvers that do not support stochasticity"""
    field = ScalarField.random_uniform(UnitGrid([16]), -1, 1)
    eq = DiffusionPDE(noise=1)

    with pytest.raises(RuntimeError):
        eq.solve(field, 1, method="explicit", scheme="runge-kutta", tracker=None)
    with pytest.raises(RuntimeError):
        eq.solve(field, 1, method="scipy", scheme="runge-kutta", tracker=None)
示例#16
0
def test_gradient_cart(ndim):
    """test different gradient operators"""
    for periodic in [True, False]:
        bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic=periodic)
        field = ScalarField.random_uniform(bcs.grid)
        res1 = field.gradient(bcs, backend="scipy").data
        res2 = field.gradient(bcs, backend="numba").data
        assert res1.shape == (ndim,) + bcs.grid.shape
        np.testing.assert_allclose(res1, res2)
示例#17
0
def test_degenerated_grid():
    """test operators on grids with singular dimensions"""
    g1 = CartesianGrid([[0, 1]], 4)
    g2 = CartesianGrid([[0, 1], [0, 0.1]], [4, 1], periodic=[False, True])
    f1 = ScalarField.random_uniform(g1)
    f2 = ScalarField(g2, f1.data.reshape(g2.shape))

    res1 = f1.laplace("auto_periodic_neumann").data
    res2 = f2.laplace("auto_periodic_neumann").data
    np.testing.assert_allclose(res1.flat, res2.flat)
示例#18
0
def test_pde_wrong_input():
    """ test some wrong input """
    with pytest.raises(RuntimeError):
        PDE({"t": 1})

    grid = grids.UnitGrid([4])
    eq = PDE({"u": 1})
    assert eq.expressions == {"u": "1.0"}
    with pytest.raises(ValueError):
        eq.evolution_rate(FieldCollection.scalar_random_uniform(2, grid))

    eq = PDE({"u": 1, "v": 2})
    assert eq.expressions == {"u": "1.0", "v": "2.0"}
    with pytest.raises(ValueError):
        eq.evolution_rate(ScalarField.random_uniform(grid))

    eq = PDE({"u": "a"})
    with pytest.raises(RuntimeError):
        eq.evolution_rate(ScalarField.random_uniform(grid))
示例#19
0
def test_simple_diffusion_value():
    """test a simple diffusion equation with constant boundaries"""
    grid = CartesianGrid([[0, 1]], [16])
    c = ScalarField.random_uniform(grid, 0, 1)
    b_l = {"type": "value", "value": 0}
    b_r = {"type": "value", "value": 1}
    pde = DiffusionPDE(bc=[b_l, b_r])
    sol, info = pde.solve(c, t_range=1, dt=0.001, tracker=None, ret_info=True)
    assert isinstance(info, dict)
    np.testing.assert_allclose(sol.data, grid.axes_coords[0], rtol=5e-3)
示例#20
0
def test_small_tracker_dt():
    """test the case where the dt of the tracker is smaller than the dt
    of the simulation"""
    storage = MemoryStorage()
    pde = DiffusionPDE()
    c0 = ScalarField.random_uniform(UnitGrid([4, 4]), 0.1, 0.2)
    pde.solve(
        c0, 1e-2, dt=1e-3, method="explicit", tracker=storage.tracker(interval=1e-4)
    )
    assert len(storage) == 11
示例#21
0
def test_stochastic_adaptive_solver(caplog):
    """test using an adaptive, stochastic solver"""
    field = ScalarField.random_uniform(UnitGrid([16]), -1, 1)
    eq = DiffusionPDE(noise=1e-6)

    with caplog.at_level(logging.WARNING):
        solver = ExplicitSolver(eq, backend="numpy", adaptive=True)

    c = Controller(solver, t_range=1, tracker=None)
    c.run(field, dt=1e-2)

    assert "fixed" in caplog.text
示例#22
0
def test_plot_movie_tracker(tmp_path):
    """ test whether the plot tracker creates files without errors """
    output_file = tmp_path / "movie.mov"

    grid = UnitGrid([4, 4])
    state = ScalarField.random_uniform(grid)
    pde = DiffusionPDE()
    tracker = trackers.PlotTracker(movie=output_file, interval=0.1, show=False)

    pde.solve(state, t_range=0.5, dt=0.005, tracker=tracker, backend="numpy")

    assert output_file.stat().st_size > 0
示例#23
0
def test_poisson_solver_spherical():
    """test the poisson solver on Polar grids"""
    for grid in [SphericalSymGrid(4, 8), SphericalSymGrid([2, 4], 8)]:
        for bc_val in ["auto_periodic_neumann", {"value": 1}]:
            bcs = grid.get_boundary_conditions(bc_val)
            d = ScalarField.random_uniform(grid)
            d -= d.average  # balance the right hand side
            sol = solve_poisson_equation(d, bcs)
            test = sol.laplace(bcs)
            np.testing.assert_allclose(
                test.data, d.data, err_msg=f"bcs={bc_val}, grid={grid}", rtol=1e-6
            )
示例#24
0
def test_material_conservation_tracker():
    """ test the MaterialConservationTracker """
    state = ScalarField.random_uniform(UnitGrid([8, 8]), 0, 1)

    solver = ExplicitSolver(CahnHilliardPDE())
    controller = Controller(solver, t_range=1, tracker=["material_conservation"])
    controller.run(state, dt=1e-3)
    assert controller.info["t_final"] >= 1

    solver = ExplicitSolver(AllenCahnPDE())
    controller = Controller(solver, t_range=1, tracker=["material_conservation"])
    controller.run(state, dt=1e-3)
    assert controller.info["t_final"] <= 1
示例#25
0
def test_no_dt():
    """ test scipy solver without timestep """
    grid = UnitGrid([16])
    field = ScalarField.random_uniform(grid, -1, 1)
    eq = DiffusionPDE()

    c1 = Controller(ScipySolver(eq), t_range=1, tracker=None)
    s1 = c1.run(field, dt=1e-3)

    c2 = Controller(ScipySolver(eq), t_range=1, tracker=None)
    s2 = c2.run(field)

    np.testing.assert_allclose(s1.data, s2.data, rtol=1e-3, atol=1e-3)
示例#26
0
def test_diffusion_single():
    """test some methods of the simple diffusion model"""
    eq = DiffusionPDE()
    assert isinstance(str(eq), str)
    assert isinstance(repr(eq), str)
    assert not eq.explicit_time_dependence

    grid = UnitGrid([4, 4])
    state = ScalarField.random_uniform(grid)

    field = eq.evolution_rate(state)
    assert isinstance(field, ScalarField)
    assert field.grid == grid
示例#27
0
def test_singular_dimensions_3d(periodic):
    """test grids with singular dimensions"""
    dim = np.random.randint(3, 5)
    g1 = UnitGrid([dim], periodic=periodic)
    g3a = UnitGrid([dim, 1, 1], periodic=periodic)
    g3b = UnitGrid([1, 1, dim], periodic=periodic)

    field = ScalarField.random_uniform(g1)
    expected = field.laplace("auto_periodic_neumann").data
    for g in [g3a, g3b]:
        f = ScalarField(g, data=field.data.reshape(g.shape))
        res = f.laplace("auto_periodic_neumann").data.reshape(g1.shape)
        np.testing.assert_allclose(expected, res)
def test_shapes_nfields(example_grid):
    """ test single component field """
    for num in [1, 3]:
        fields = [ScalarField.random_uniform(example_grid) for _ in range(num)]
        field = FieldCollection(fields)
        data_shape = (num,) + example_grid.shape
        np.testing.assert_equal(field.data.shape, data_shape)
        for pf_single in field:
            np.testing.assert_equal(pf_single.data.shape, example_grid.shape)

        field_c = field.copy()
        np.testing.assert_allclose(field.data, field_c.data)
        assert field.grid == field_c.grid
示例#29
0
def test_compare_solvers(solver_class):
    """compare several solvers"""
    field = ScalarField.random_uniform(UnitGrid([8, 8]), -1, 1)
    eq = DiffusionPDE()

    # ground truth
    c1 = Controller(ExplicitSolver(eq, scheme="runge-kutta"), t_range=0.1, tracker=None)
    s1 = c1.run(field, dt=5e-3)

    c2 = Controller(solver_class(eq), t_range=0.1, tracker=None)
    with np.errstate(under="ignore"):
        s2 = c2.run(field, dt=5e-3)

    np.testing.assert_allclose(s1.data, s2.data, rtol=1e-2, atol=1e-2)
def test_compare_explicit():
    """ test explicit solvers """
    grid = UnitGrid([16, 16])
    field = ScalarField.random_uniform(grid, -1, 1)
    eq = DiffusionPDE()

    c1 = Controller(ExplicitSolver(eq), t_range=0.1, tracker=None)
    s1 = c1.run(field, dt=2e-3)

    c2 = Controller(ExplicitSolver(eq, scheme="runge-kutta"), t_range=0.1, tracker=None)
    with np.errstate(under="ignore"):
        s2 = c2.run(field, dt=2e-3)

    np.testing.assert_allclose(s1.data, s2.data, rtol=1e-2, atol=1e-2)