Quick Start: Scalar Transport
This notebook demonstrates a minimal transient scalar transport setup: a Gaussian pulse advected through a 2D channel using HDG with BDF2 time integration.
[1]:
import numpy as np
import ngsolve as ngs
from dream.mesh import get_rectangular_mesh
from dream.scalar_transport import ScalarTransportSolver, transportfields
from dream.scalar_transport.config import FarField, Initial
ngs.SetNumThreads(12)
[2]:
# Build a simple channel mesh
nx = np.linspace(0.0, 4.0, 41)
ny = np.linspace(-0.5, 0.5, 11)
mesh = get_rectangular_mesh(
[("channel", (nx, ny))],
[("inflow", (np.array([0.0]), ny)),
("outflow", (np.array([4.0]), ny)),
("wall", (nx, np.array([-0.5]))),
("wall", (nx, np.array([ 0.5])))],
)
[3]:
solver = ScalarTransportSolver(mesh)
# Physical parameters
solver.convection_velocity = ngs.CF((1.0, 0.0))
solver.diffusion_coefficient = 1e-3
# Discretisation
solver.fem = 'hdg'
solver.fem.order = 3
solver.riemann_solver = 'lax_friedrich'
# Time integration
solver.time = 'transient'
solver.fem.scheme = 'bdf2'
solver.time.timer.interval = (0.0, 2.0)
solver.time.timer.step = 5e-3
# Boundary and initial conditions
Uinf = transportfields(u=0.0)
U0 = transportfields(u=ngs.exp(-50 * (ngs.y**2)))
solver.bcs['inflow'] = FarField(fields=U0)
solver.bcs['outflow'] = FarField(fields=Uinf)
solver.dcs['channel'] = Initial(fields=transportfields(u=0.0))
# with ngs.TaskManager():
# # Sets up finite element spaces, assembles bilinear forms and applies boundary conditions
# solver.initialize()
# # Runs the time-stepping loop defined by solver.time
# solver.solve()