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
def integrate(tfinal, u, u2, udiff, IC): grid = CartesianGrid([[0, 200]], 200) field = ScalarField(grid, IC) storage = MemoryStorage() eq = libraryPDE(u, u2, udiff) #define PDE with custom parameters return eq.solve(field, t_range=tfinal, dt=0.1, tracker=storage.tracker(0.1)).data
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
def test_pde_time_dependent_bcs(backend): """test PDE with time-dependent BCs""" field = ScalarField(grids.UnitGrid([3])) eq = PDE({"c": "laplace(c)"}, 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_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
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()
def test_solvers_simple_ode(scheme, adaptive): """test explicit solvers with a simple ODE""" grid = UnitGrid([1]) field = ScalarField(grid, 1) eq = PDE({"y": "2*sin(t) - y"}) dt = 1e-3 if scheme == "euler" else 1e-2 storage = MemoryStorage() solver = ExplicitSolver(eq, scheme=scheme, adaptive=adaptive) controller = Controller(solver, t_range=20.0, tracker=storage.tracker(1)) controller.run(field, dt=dt) ts = np.ravel(storage.times) expect = 2 * np.exp(-ts) - np.cos(ts) + np.sin(ts) np.testing.assert_allclose(np.ravel(storage.data), expect, atol=0.05) if adaptive: assert solver.info["steps"] < 20 / dt else: assert solver.info["steps"] == pytest.approx(20 / dt, abs=1)
def main(): #ture需要小写,f'string'string里面有{}可以传递全局参数参数 eq = Heat_trans() 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()
using the :class:`~pde.pdes.pde.PDE` class. In particular, we consider :math:`D(x) = 1.01 + \tanh(x)`, which gives a low diffusivity on the left side of the domain. Note that the naive implementation, :code:`PDE({"c": "divergence((1.01 + tanh(x)) * gradient(c))"})`, has numerical instabilities. This is because two finite difference approximations are nested. To arrive at a more stable numerical scheme, it is advisable to expand the divergence, .. math:: \partial_t c = D \nabla^2 c + \nabla D . \nabla c """ from pde import PDE, CartesianGrid, MemoryStorage, ScalarField, plot_kymograph # Expanded definition of the PDE diffusivity = "1.01 + tanh(x)" term_1 = f"({diffusivity}) * laplace(c)" term_2 = f"dot(gradient({diffusivity}), gradient(c))" eq = PDE({"c": f"{term_1} + {term_2}"}, bc={"value": 0}) grid = CartesianGrid([[-5, 5]], 64) # generate grid field = ScalarField(grid, 1) # generate initial condition storage = MemoryStorage() # store intermediate information of the simulation res = eq.solve(field, 100, dt=1e-3, tracker=storage.tracker(1)) # solve the PDE plot_kymograph(storage) # visualize the result in a space-time plot
((25+{T_Kelvin}),true)).subs(tt,t))' grid = CartesianGrid([[0, x_max]], [int(xstep)]) state = ScalarField(grid=grid, data=T_origin + T_Kelvin) eq = PDE( rhs={'c': f'{alpha}*laplace(c)'}, bc={ 'type': 'mixed', 'value': -1 * h / llambda, 'const': bc_T }, ) #bc_ops={}) 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()
#!/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')
\partial_t \phi = 6 \phi \partial_x \phi - \partial_x^2 \phi which we implement using a custom PDE class below. """ from math import pi from pde import CartesianGrid, MemoryStorage, PDEBase, ScalarField, plot_kymograph class KortewegDeVriesPDE(PDEBase): """ Korteweg-de Vries equation """ def evolution_rate(self, state, t=0): """ implement the python version of the evolution equation """ assert state.grid.dim == 1 # ensure the state is one-dimensional grad = state.gradient("natural")[0] return 6 * state * grad - grad.laplace("natural") # initialize the equation and the space grid = CartesianGrid([[0, 2 * pi]], [32], periodic=True) state = ScalarField.from_expression(grid, "sin(x)") # solve the equation and store the trajectory storage = MemoryStorage() eq = KortewegDeVriesPDE() eq.solve(state, t_range=3, tracker=storage.tracker(0.1)) # plot the trajectory as a space-time plot plot_kymograph(storage)
from math import pi from pde import (CartesianGrid, ScalarField, PDEBase, MemoryStorage, plot_kymograph) class KortewegDeVriesPDE(PDEBase): """ Korteweg-de Vries equation See https://en.wikipedia.org/wiki/Korteweg–de_Vries_equation """ def evolution_rate(self, state, t=0): """ implement the python version of the evolution equation """ assert state.grid.dim == 1 # ensure the state is one-dimensional grad = state.gradient('natural')[0] return 6 * state * grad - grad.laplace('natural') # initialize the equation and the space grid = CartesianGrid([[0, 2 * pi]], [32], periodic=True) state = ScalarField.from_expression(grid, "sin(x)") eq = KortewegDeVriesPDE() # solve the equation and store the trajectory storage = MemoryStorage() eq.solve(state, t_range=3, tracker=['progress', storage.tracker(.1)]) # plot the trajectory as a space-time plot plot_kymograph(storage, show=True)
This example implements a complex PDE using the :class:`~pde.pdes.pde.PDE`. We here chose the `Schrödinger equation <https://en.wikipedia.org/wiki/Schrödinger_equation>`_ without a spatial potential in non-dimensional form: .. math:: i \partial_t \psi = -\nabla^2 \psi Note that the example imposes Neumann conditions at the wall, so the wave packet is expected to reflect off the wall. """ from math import sqrt from pde import PDE, CartesianGrid, MemoryStorage, ScalarField, plot_kymograph grid = CartesianGrid([[0, 20]], 128, periodic=False) # generate grid # create a (normalized) wave packet with a certain form as an initial condition initial_state = ScalarField.from_expression( grid, "exp(I * 5 * x) * exp(-(x - 10)**2)") initial_state /= sqrt(initial_state.to_scalar("norm_squared").integral.real) eq = PDE({"ψ": f"I * laplace(ψ)"}) # define the pde # solve the pde and store intermediate data storage = MemoryStorage() eq.solve(initial_state, t_range=2.5, dt=1e-5, tracker=[storage.tracker(0.02)]) # visualize the results as a space-time plot plot_kymograph(storage, scalar="norm_squared")
def test_field_type_guessing(): """ test the ability to guess the field type """ for cls in [ScalarField, VectorField, Tensor2Field]: grid = UnitGrid([3]) field = cls.random_normal(grid) s = MemoryStorage() s.start_writing(field) s.append(field, 0) s.append(field, 1) # delete information s._field = None s.info = {} assert not s.has_collection assert len(s) == 2 assert s[0] == field field = FieldCollection([ScalarField(grid), VectorField(grid)]) s = MemoryStorage() s.start_writing(field) s.append(field, 0) assert s.has_collection # delete information s._field = None s.info = {} with pytest.raises(RuntimeError): s[0]
def test_memory_storage(): """ test methods specific to memory storage """ sf = ScalarField(UnitGrid([1])) s1 = MemoryStorage() s1.start_writing(sf) s1.append(sf.copy(data=0), 0) s1.append(sf.copy(data=2), 1) s2 = MemoryStorage() s2.start_writing(sf) s2.append(sf.copy(data=1), 0) s2.append(sf.copy(data=3), 1) # test from_fields s3 = MemoryStorage.from_fields(s1.times, [s1[0], s1[1]]) assert s3.times == s1.times np.testing.assert_allclose(s3.data, s1.data) # test from_collection s3 = MemoryStorage.from_collection([s1, s2]) assert s3.times == s1.times np.testing.assert_allclose(np.ravel(s3.data), np.arange(4))
#!/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)
def test_storage_copy(tmp_path): """ test the copy function of StorageBase """ grid = UnitGrid([2]) field = ScalarField(grid) storage_classes = {"None": None, "MemoryStorage": MemoryStorage} if module_available("h5py"): file_path = tmp_path / "test_storage_apply.hdf5" storage_classes["FileStorage"] = functools.partial( FileStorage, file_path) s1 = MemoryStorage() s1.start_writing(field, info={"b": 2}) s1.append(field.copy(data=np.array([0, 1])), 0) s1.append(field.copy(data=np.array([1, 2])), 1) s1.end_writing() for name, storage_cls in storage_classes.items(): out = None if storage_cls is None else storage_cls() s2 = s1.copy(out=out) assert storage_cls is None or s2 is out assert len(s2) == 2 np.testing.assert_allclose(s2.times, s1.times) assert s2[0] == s1[0], name assert s2[1] == s1[1], name # test empty storage s1 = MemoryStorage() s2 = s1.copy() assert len(s2) == 0
""" Stochastic simulation ===================== This example illustrates how a stochastic simulation can be done. """ from pde import (KPZInterfacePDE, UnitGrid, ScalarField, MemoryStorage, plot_kymograph) grid = UnitGrid([64]) # generate grid state = ScalarField.random_harmonic(grid) # generate initial condition eq = KPZInterfacePDE(noise=1) # define the SDE storage = MemoryStorage() eq.solve(state, t_range=10, dt=0.01, tracker=storage.tracker(0.5)) plot_kymograph(storage)
""" Time-dependent boundary conditions ================================== This example solves a simple diffusion equation in one dimensions with time-dependent boundary conditions. """ from pde import PDE, CartesianGrid, MemoryStorage, ScalarField, plot_kymograph grid = CartesianGrid([[0, 10]], [64]) # generate grid state = ScalarField(grid) # generate initial condition eq = PDE({"c": "laplace(c)"}, bc={"value_expression": "sin(t)"}) storage = MemoryStorage() eq.solve(state, t_range=20, dt=1e-4, tracker=storage.tracker(0.1)) # plot the trajectory as a space-time plot plot_kymograph(storage)
(195+273.15,And(202.5<tt,tt<=233)), \ (195+8*tt+273.15,And(233<tt,tt<=238)), \ (235+273.15,And(238<tt,tt<=268.5)), \ (235+4*tt+273.15,And(268.5<tt,tt<=273.5)), \ (255+273.15,And(273.5<tt,tt<=344.5)), \ (255-(230/91)*tt+273.15,And(344.5<tt,tt<=435.5)), \ (25+273.15,And(435.5<tt,tt<=500))).subs(tt,t))' grid = CartesianGrid([[0, x_max]], [int(xstep)]) state=ScalarField(grid=grid,data=T_origin+T_Kelvin) eq = PDE(rhs={'c': 'a*laplace(c)'}, bc={'value_expression': bc_T}, consts={'a':alpha}) storage = MemoryStorage() eq.solve(state, t_range=tmax, tracker=storage.tracker(tstep)) def kymograph_pic(): plot_kymograph(storage) def temp_curve(): p=[] for i in range(int(tmax/tstep)): p.append(storage.data[i][-1]) q=np.asarray(p) plt.plot(np.linspace(0,tmax,int(tmax/tstep),endpoint=1),q,label='Temperature') plt.xlabel('Time') plt.ylabel('Temprature') plt.show()