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) sf.data = 0 s1.append(sf, 0) sf.data = 2 s1.append(sf, 1) s2 = MemoryStorage() s2.start_writing(sf) sf.data = 1 s2.append(sf, 0) sf.data = 3 s2.append(sf, 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))
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
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 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 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()
#!/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)
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