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
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")
Exemple #3
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)
Exemple #4
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
Exemple #5
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)
Exemple #6
0
def test_inhomogeneous_bcs():
    """ test simulation with inhomogeneous boundary conditions """
    grid = CartesianGrid([[0, 2 * np.pi], [0, 1]], [32, 2],
                         periodic=[True, False])
    state = ScalarField(grid)
    pde = DiffusionPDE(bc=["natural", {"type": "value", "value": "sin(x)"}])
    sol = pde.solve(state, t_range=1e1, dt=1e-2, tracker=None)
    data = sol.get_line_data(extract="project_x")
    np.testing.assert_almost_equal(data["data_y"],
                                   0.9 * np.sin(data["data_x"]),
                                   decimal=2)
Exemple #7
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
def test_length_scale_tracker(tmp_path):
    """test the length scale tracker"""
    path = tmp_path / "test_length_scale_tracker.json"

    grid = CartesianGrid([[0, 10 * np.pi]], 64, periodic=True)
    field = ScalarField.from_expression(grid, "sin(2 * x)")

    pde = DiffusionPDE()
    tracker = LengthScaleTracker(0.05, filename=path)
    pde.solve(field, t_range=0.1, backend="numpy", tracker=tracker)

    for ls in tracker.length_scales:
        assert ls == pytest.approx(np.pi, rel=1e-3)
    assert path.stat().st_size > 0  # wrote some result
Exemple #9
0
def test_diffusion_time_dependent_bcs(backend):
    """test PDE with time-dependent BCs"""
    field = ScalarField(UnitGrid([3]))

    eq = DiffusionPDE(bc={"value_expression": "Heaviside(t - 1.5)"})

    storage = MemoryStorage()
    eq.solve(field,
             t_range=10,
             dt=1e-2,
             backend=backend,
             tracker=storage.tracker(1))

    np.testing.assert_allclose(storage[1].data, 0)
    np.testing.assert_allclose(storage[-1].data, 1, rtol=1e-3)
def test_stochastic_solvers(backend):
    """ test simple version of the stochastic solver """
    field = ScalarField.random_uniform(UnitGrid([16]), -1, 1)
    eq = DiffusionPDE()
    seq = DiffusionPDE(noise=1e-6)

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

    solver2 = ExplicitSolver(seq, backend=backend)
    c2 = Controller(solver2, t_range=1, tracker=None)
    s2 = c2.run(field, dt=1e-3)

    np.testing.assert_allclose(s1.data, s2.data, rtol=1e-4, atol=1e-4)
    assert not solver1.info["stochastic"]
    assert solver2.info["stochastic"]
Exemple #11
0
def main():
    xstep=5
    tstep=1
    v=73.82/60#Unit:cm/s
    tmin=0
    tmax=500
    bc_T=f'-1*{llambda}/{h}*c.diff(x)+(Piecewise(\
        ((25+{T_Kelvin}),tt<=20/{v}),\
        ((25+150/{v}*(tt-20/{v})+{T_Kelvin}),And(20/{v}<tt,tt<=25/{v})),\
        ((175+{T_Kelvin}),And(25/{v}<tt,tt<=197.5/{v})),\
        ((175+20/{v}*(tt-197.5/{v})+{T_Kelvin}),And(197.5/{v}<tt,tt<=202.5/{v})),\
        ((195+{T_Kelvin}),And(202.5/{v}<tt,tt<=233/{v})),\
        ((195+40/{v}*(tt-233/{v})+{T_Kelvin}),And(233/{v}<tt,tt<=238/{v})),\
        ((235+{T_Kelvin}),And(238/{v}<tt,tt<=268.5/{v})),\
        ((235+20/{v}*(tt-268.5/{v})+{T_Kelvin}),And(268.5/{v}<tt,tt<=273.5/{v})),\
        ((255+{T_Kelvin}),And(273.5/{v}<tt,tt<=344.5/{v})),\
        ((255-230/{v}*(tt-344.5/{v})+{T_Kelvin}),And(344.5/{v}<tt,tt<=435.5/{v})),\
        ((25+{T_Kelvin}),true)).subs(tt,t))' 
        #ture需要小写,f'string'string里面有{}可以传递全局参数参数
    grid = CartesianGrid([[0, x_max]], [int(xstep)],periodic=False)
    state=ScalarField(grid=grid,data=T_origin+T_Kelvin)

    eq = DiffusionPDE(diffusivity=alpha, bc={'value_expression':bc_T},)

    storage = MemoryStorage()
    eq.solve(state, t_range=(tmin,tmax),dt=1e-3, tracker=storage.tracker(tstep))

    def temp_curve():
        p=[]
        for i in range(int((tmax-tmin)/tstep)):
            p.append(storage.data[i][-1])
    
        q=np.asarray(p)
        plt.plot(np.linspace(tmin,tmax,int((tmax-tmin)/tstep),endpoint=0),q,label='Temperature')
        plt.xlabel('Time')
        plt.ylabel('Temprature')
        plt.show()

    def plotky():
        plot_kymograph(storage)

    #temp_curve()
    plotky()
Exemple #12
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
def test_storage_truncation(tmp_path):
    """ test whether simple trackers can be used """
    file = tmp_path / "test_storage_truncation.hdf5"
    for truncate in [True, False]:
        storages = [MemoryStorage()]
        if module_available("h5py"):
            storages.append(FileStorage(file))
        tracker_list = [s.tracker(interval=0.01) for s in storages]

        grid = UnitGrid([8, 8])
        state = ScalarField.random_uniform(grid, 0.2, 0.3)
        pde = DiffusionPDE()

        pde.solve(state, t_range=0.1, dt=0.001, tracker=tracker_list)
        if truncate:
            for storage in storages:
                storage.clear()
        pde.solve(state, t_range=[0.1, 0.2], dt=0.001, tracker=tracker_list)

        times = np.arange(0.1, 0.201, 0.01)
        if not truncate:
            times = np.r_[np.arange(0, 0.101, 0.01), times]
        for storage in storages:
            msg = f"truncate={truncate}, storage={storage}"
            np.testing.assert_allclose(storage.times, times, err_msg=msg)

        assert not storage.has_collection
Exemple #14
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)
Exemple #15
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)
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)
Exemple #18
0
def test_inhomogeneous_bcs():
    """test simulation with inhomogeneous boundary conditions"""
    # single coordinate
    grid = CartesianGrid([[0, 2 * np.pi], [0, 1]], [32, 2],
                         periodic=[True, False])
    state = ScalarField(grid)
    pde = DiffusionPDE(
        bc=["auto_periodic_neumann", {
            "type": "value",
            "value": "sin(x)"
        }])
    sol = pde.solve(state, t_range=1e1, dt=1e-2, tracker=None)
    data = sol.get_line_data(extract="project_x")
    np.testing.assert_almost_equal(data["data_y"],
                                   0.9 * np.sin(data["data_x"]),
                                   decimal=2)

    # double coordinate
    grid = CartesianGrid([[0, 1], [0, 1]], [8, 8], periodic=False)
    state = ScalarField(grid)
    pde = DiffusionPDE(bc={"type": "value", "value": "x + y"})
    sol = pde.solve(state, t_range=1e1, dt=1e-3, tracker=None)
    expect = ScalarField.from_expression(grid, "x + y")
    np.testing.assert_almost_equal(sol.data, expect.data)
Exemple #19
0
#!/usr/bin/env python3

from pde import (DiffusionPDE, UnitGrid, ScalarField, MemoryStorage,
                 PlotTracker, PrintTracker, RealtimeIntervals)

eq = DiffusionPDE()  # define the pde
grid = UnitGrid([16, 16])  # generate grid
state = ScalarField.random_uniform(grid, 0.2,
                                   0.3)  # generate initial condition

storage = MemoryStorage()

trackers = [
    'progress',  # show progress bar during simulation
    'steady_state',  # abort when steady state is reached
    storage.tracker(interval=1),  # store data every simulation time unit
    PlotTracker(show=True),  # show images during simulation
    # print some output every 5 real seconds:
    PrintTracker(interval=RealtimeIntervals(duration=5))
]

eq.solve(state, 10, dt=0.1, tracker=trackers)

storage[0].plot(show=True)
"""
Solver comparison
=================

This example shows how to set up solvers explicitly and how to extract
diagnostic information.
"""

from pde import (UnitGrid, ScalarField, FieldCollection, DiffusionPDE,
                 ExplicitSolver, ScipySolver, Controller) 

# initialize the grid, an initial condition, and the PDE
grid = UnitGrid([32, 32])
field = ScalarField.random_uniform(grid, -1, 1)
eq = DiffusionPDE()

# try the explicit solver
solver1 = ExplicitSolver(eq)
controller1 = Controller(solver1, t_range=1, tracker=None)
sol1 = controller1.run(field, dt=1e-3)
sol1.label = 'explicit solver'
print('Diagnostic information from first run:')
print(controller1.diagnostics)
print()

# try the standard scipy solver
solver2 = ScipySolver(eq)
controller2 = Controller(solver2, t_range=1, tracker=None)
sol2 = controller2.run(field)
sol2.label = 'scipy solver'
print('Diagnostic information from second run:')
Exemple #21
0
def test_solver_in_pde_class():
    """ test whether solver instances can be used in pde instances """
    field = ScalarField.random_uniform(UnitGrid([16, 16]), -1, 1)
    eq = DiffusionPDE()
    eq.solve(field, t_range=1, method=ScipySolver, tracker=None)
Exemple #22
0
"""
Diffusion on a Cartesian grid
=============================

This example shows how to solve the diffusion equation on a Cartesian grid.
"""

from pde import CartesianGrid, ScalarField, DiffusionPDE

grid = CartesianGrid([[-1, 1], [0, 2]], [30, 16])  # generate grid
state = ScalarField(grid)  # generate initial condition
state.add_interpolated([0, 1], 1)

eq = DiffusionPDE()  # define the pde
result = eq.solve(state, t_range=1, dt=0.001)
result.plot()
Exemple #23
0
"""
Using simulation trackers
=========================

This example illustrates how trackers can be used to analyze simulations.
"""

from pde import (DiffusionPDE, UnitGrid, ScalarField, MemoryStorage,
                 PlotTracker, PrintTracker, RealtimeIntervals)

grid = UnitGrid([32, 32])  # generate grid
state = ScalarField.random_uniform(grid)  # generate initial condition

storage = MemoryStorage()

trackers = [
    'progress',  # show progress bar during simulation
    'steady_state',  # abort when steady state is reached
    storage.tracker(interval=1),  # store data every simulation time unit
    PlotTracker(show=True),  # show images during simulation
    # print some output every 5 real seconds:
    PrintTracker(interval=RealtimeIntervals(duration=5))
]

eq = DiffusionPDE(0.1)  # define the PDE
eq.solve(state, 3, dt=0.1, tracker=trackers)

for field in storage:
    print(field.integral)
Exemple #24
0
#!/usr/bin/env python3

from pde import UnitGrid, ScalarField, DiffusionPDE

grid = UnitGrid([16, 16], periodic=[False, True])   # generate grid
state = ScalarField.random_uniform(grid, 0.2, 0.3)  # generate initial condition

# set boundary conditions `bc` for all axes
bc_x_left = {'type': 'derivative', 'value': 0.1}  
bc_x_right = {'type': 'value', 'value': 0}
bc_x = [bc_x_left, bc_x_right]
bc_y = 'periodic' 
eq = DiffusionPDE(bc=[bc_x, bc_y])

result = eq.solve(state, t_range=10, dt=0.005)
result.plot(show=True)
Exemple #25
0
#!/usr/bin/env python3

from pde import DiffusionPDE, UnitGrid, ScalarField

eq = DiffusionPDE(diffusivity=0.1)  # define the pde
grid = UnitGrid([64, 64])  # generate grid
state = ScalarField.random_uniform(grid, 0.2,
                                   0.3)  # generate initial condition

result = eq.solve(state, t_range=10)
result.plot(show=True)
Exemple #26
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)
Exemple #27
0
#!/usr/bin/env python3

from pde import UnitGrid, ScalarField, DiffusionPDE, MemoryStorage, movie_scalar

eq = DiffusionPDE()  # define the physics
grid = UnitGrid([16, 16])  # generate grid
state = ScalarField.random_uniform(grid, 0.2,
                                   0.3)  # generate initial condition

storage = MemoryStorage()  # create storage
tracker = storage.tracker(interval=1)  # create associated tracker

eq.solve(state, t_range=2, dt=0.005, tracker=tracker)

# create movie from stored data
movie_scalar(storage, '/tmp/diffusion.mov')
Exemple #28
0
"""
Spherically symmetric PDE
=========================

This example illustrates how to solve a PDE in a spherically symmetric geometry.
"""

from pde import DiffusionPDE, SphericalGrid, ScalarField

grid = SphericalGrid(radius=[1, 5], shape=128)  # generate grid
state = ScalarField.random_uniform(grid)  # generate initial condition

eq = DiffusionPDE(0.1)  # define the PDE
result = eq.solve(state, t_range=0.1, dt=0.001)

result.plot(kind='image')