zwicker-group / py-pde

Python package for solving partial differential equations using finite differences.

Home Page:https://py-pde.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error : PDE with time dependent boundary conditions

GVE871 opened this issue · comments

Hello, I am trying to solve a simple pde with a time dependent boundary condition:

from pde import PDE, CartesianGrid, MemoryStorage, ScalarField, plot_kymographs, FieldCollection,PDEBase
import numpy as np 
from math import pi

H = 4
grid_steps=64
init_temp=1
fluid_temp=0.5

grid = CartesianGrid([[0, H]], [grid_steps], periodic=False)
Tf = ScalarField(grid,np.linspace(init_temp,init_temp,grid_steps), label="Field $Tf$")
Ts = ScalarField(grid,np.linspace(init_temp,init_temp,grid_steps), label="Field $Ts$")
state = FieldCollection([Tf,Ts])

bc_fluid_lower = {"value_expression": "sin(t)"}
bc_fluid_upper = {"derivative": 0}
bc_fluid = [bc_fluid_lower, bc_fluid_upper]

class TESPDE(PDEBase): 
    def evolution_rate(self, state, t = 0):
        d_Tf_dx=state[0].grid.make_operator("d_dx", bc_fluid)
        return FieldCollection([-d_Tf_dx(state[0].data) + (state[1]  -state[0]) , (state[1] - state[0])])

eq = TESPDE()

# simulate the pde
storage = MemoryStorage()
sol=eq.solve(state, t_range=1,dt=0.01, solver="scipy", tracker=storage.tracker(1.))
plot_kymographs(storage)

but I get the error

TypingError                               Traceback (most recent call last)
.
.
.
File "..\..\..\AppData\Local\anaconda3\Lib\site-packages\pde\grids\base.py", line 1471:
            def apply_op_compiled(
                <source elided>
                """set boundary conditions and apply operator"""
                return apply_op(arr, out, args)
                ^

Time-dependent boundary conditions are a bit more complicated to use since the operator (which applies the boundary condition) actually needs to know the current time. I suggest the following solution:

class TESPDE(PDEBase):
    def evolution_rate(self, state, t=0):
        return FieldCollection(
            [
                -state[0].gradient(bc_fluid, args={"t": t}) + (state[1] - state[0]),
                (state[1] - state[0]),
            ]
        )

Note that I replaced the state[0].grid.make_operator call by a simple gradient, which is more efficient since otherwise make_operator would be called each time step.

That fixed it thanks