Skip to content

Interface for PDE solver on more general domains #5

@termi-official

Description

@termi-official

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 $\Omega$ is not discretized at this point) and 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 the RitzGalerkin 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions