-
-
Notifications
You must be signed in to change notification settings - Fork 8
Description
This package has potential to be a solid foundation as being the interface between ModelingToolkit.jl and several FEM/FVM/DG/... packages, which can solve PDE-based models on unstructured domains. We also might want to use some PDE discretizers to derive a system of ODEs or DAEs, which can then be fed into DifferentialEquations.jl for time integration.
A good first start might be to figure out how the interface might look like in 1D before moving forward to higher dimensions (which also might require interaction with some geometric discretizer). As a first step let us setup a steady state heat problem via ModelingToolkit.jl in strong form. From my understanding this can be done as follows (with some shortcuts taken for now):
using ModelingToolkit, SciMLBase
import Symbolics: ClosedInterval
@parameters x₁ f
@variables u(..)
Ω = ClosedInterval(0,1)
# TODO correct definitions.
grad(var) = Differential(x₁)(var)
div(var) = Differential(x₁)(var)
eqs = [div(grad(u)) ~ f]
bcs = [u(0.0) ~ 0., u(1.0) ~ 0.]
@named pde = PDESystem(eqs,bcs,[Ω],[x₁],[u(x₁)])
disc = MyFrameworkDiscretization(RitzGalerkin(...), TessellationInfo(...), MyFrameworkInfo(...))
prob = discretize(pdesys, disc, kwargs_to_prob...)
where RitzGalerkin
is a type to describe general finite element discretizations of a PDE problem. This step is likely independent of the chosen framework. The symbolic discretization should hold information required for building the system of equation on some finite element. (Let us ignore trace spaces and the fancy stuff for now.) Further TessellationInfo
is information regarding the geometric discretization of the domain (assuming that PDEFrameworkInfo
carries all framework specific information to assemble the linear problem. The resulting linear problem can then be solved by some solver from LinearSolve.jl.
For finite element discretizations we start with rewriting the problem into some weak form. With the current interface this should be done by dispatching should_transform
and transform_pde_system
. This will also introduces new variables for the test spaces, which have to be introduced without collision with existing symbols. The resulting system for the standard formulation for the heat problem using H1 ansatz space should be equivalent to:
using ModelingToolkit, LinearAlgebra
import Symbolics: ClosedInterval
@parameters x₁ f
@variables u(..) v(..)
Ω = (x₁ ∈ ClosedInterval(0,1))
∫ = Integral(Ω)
# TODO correct definitions.
grad(var) = Differential(x₁)(var)
# Bilinear form
a(u,v) = ∫(grad(u) ⋅ grad(v))
# Linear form
b(v) = ∫(f*v)
# System
eqs_weak = [a(u(x₁),v(x₁)) ~ b(v(x₁))]
bcs = [u(0.0) ~ 0., u(1.0) ~ 0.]
@named pde = PDESystem(eqs_weak,bcs,[Ω],[x₁],[u(x₁)])
where v
is the introduced test variable. Automatizing the transformations should be the smaller issue here. It should also be possible to directly feed the weak problem into the PDESystem and discretize it. Four more functions remain to be dispatched, with my understanding of what they should do as comments following them:
-
PDEBase.construct_discrete_space
I am not sure what exactly this one should do -
PDEBase.construct_disc_state
for example, if we have a quadrilateral as our element (e.g. from theRitzGalerkin
struct), linear Lagrange ansatz space and the heat problem as stated above, then this should return 4 discrete variables for$u$ ($\hat{u}_1,...\hat{u}_4$ ) and an additional 4 variables for$v$ ($\hat{v}_1,...,\hat{v}_4$ ). -
PDEBase.discretize_equation!
I think this should replace$u(x_1)$ with$\sum_i \hat{u}_i \phi_i(x_1)$ , where$\phi_i$ is the local ansatz funciton, and$v$ with$\phi_1,...,\phi_4$ , such that we have 4 discrete equations. Further, the the unknown is taken out of the integral (coming from above) and the remaining integral is either resolved analytically or replaced with numerical quadrature.
The detailed process is written down here https://ferrite-fem.github.io/Ferrite.jl/stable/manual/fe_intro/ where I tried to keep the symbols used in this issue consistent with this reference.
cc @koehlerson