11"""
22Descriptor for a finite element discretization of a part of a PDE over some subdomain.
3+
4+ !!! note
5+ The current implementation is restricted to Bubnov-Galerkin methods. Petrov-Galerkin support will come in the future.
36"""
47struct FiniteElementDiscretization
58 """
69 """
7- interpolations:: Dict{Symbol, InterpolationCollection}
10+ interpolations:: Dict{Symbol} # , Union{<: InterpolationCollection, Pair{<:InterpolationCollection, <:QuadratureRuleCollection}} }
811 """
912 """
1013 dbcs:: Vector{Dirichlet}
@@ -13,17 +16,42 @@ struct FiniteElementDiscretization
1316 subdomains:: Vector{String}
1417 """
1518 """
16- function FiniteElementDiscretization (ips:: Dict{Symbol, <: InterpolationCollection} , dbcs:: Vector{Dirichlet} = Dirichlet[], subdomains:: Vector{String} = [" " ])
17- new (ips, dbcs, subdomains)
19+ mass_qrc:: Union{<:QuadratureRuleCollection,Nothing} # TODO maybe an "extras" field should be used instead :)
20+ """
21+ """
22+ function FiniteElementDiscretization (ips:: Dict{Symbol} , dbcs:: Vector{Dirichlet} = Dirichlet[], subdomains:: Vector{String} = [" " ], mass_qrc = nothing )
23+ new (ips, dbcs, subdomains, mass_qrc)
1824 end
1925end
2026
27+ _extract_ipc (ipc:: InterpolationCollection ) = ipc
28+ _extract_ipc (p:: Pair{<:InterpolationCollection, <:QuadratureRuleCollection} ) = first (p)
29+
30+ function _extract_qrc (ipc:: InterpolationCollection )
31+ ansatzorder = getorder (ipc)
32+ return QuadratureRuleCollection (max (2 ansatzorder- 1 ,2 ))
33+ end
34+ _extract_qrc (p:: Pair{<:InterpolationCollection, <:QuadratureRuleCollection} ) = last (p)
35+
2136# Internal utility with proper error message
2237function _get_interpolation_from_discretization (disc:: FiniteElementDiscretization , sym:: Symbol )
2338 if ! haskey (disc. interpolations, sym)
2439 error (" Finite element discretization does not have an interpolation for $sym . Available symbols: $(collect (keys (disc. interpolations))) ." )
2540 end
26- return disc. interpolations[sym]
41+ return _extract_ipc (disc. interpolations[sym])
42+ end
43+ function _get_quadrature_from_discretization (disc:: FiniteElementDiscretization , sym:: Symbol )
44+ if ! haskey (disc. interpolations, sym)
45+ error (" Finite element discretization does not have an interpolation for $sym . Available symbols: $(collect (keys (disc. interpolations))) ." )
46+ end
47+ return _extract_qrc (disc. interpolations[sym])
48+ end
49+ function _get_facet_quadrature_from_discretization (disc:: FiniteElementDiscretization , sym:: Symbol )
50+ if ! haskey (disc. interpolations, sym)
51+ error (" Finite element discretization does not have an interpolation for $sym . Available symbols: $(collect (keys (disc. interpolations))) ." )
52+ end
53+ intorder = getorder (_extract_ipc (disc. interpolations[sym]))
54+ return FacetQuadratureRuleCollection (intorder)
2755end
2856
2957semidiscretize (:: CoupledModel , discretization, mesh:: AbstractGrid ) = @error " No implementation for the generic discretization of coupled problems available yet."
@@ -33,22 +61,34 @@ function semidiscretize(model::TransientDiffusionModel, discretization::FiniteEl
3361
3462 sym = model. solution_variable_symbol
3563 ipc = _get_interpolation_from_discretization (discretization, sym)
64+ qrc = _get_quadrature_from_discretization (discretization, sym)
3665 dh = DofHandler (mesh)
3766 for name in discretization. subdomains
3867 add_subdomain! (dh, name, [ApproximationDescriptor (sym, ipc)])
3968 end
4069 close! (dh)
4170
42- return TransientDiffusionFunction (
43- model. κ,
44- model. source,
45- dh
71+ T = get_coordinate_eltype (get_grid (dh))
72+ return AffineODEFunction (
73+ BilinearMassIntegrator (
74+ ConstantCoefficient (T (1.0 )),
75+ discretization. mass_qrc === nothing ? qrc : mass_qrc, # Allow e.g. mass lumping for explicit integrators.
76+ sym,
77+ ),
78+ BilinearDiffusionIntegrator (
79+ model. κ,
80+ qrc,
81+ sym,
82+ ),
83+ model. source, # TODO qrc for source term
84+ dh,
4685 )
4786end
4887
4988function semidiscretize (model:: SteadyDiffusionModel , discretization:: FiniteElementDiscretization , mesh:: AbstractGrid )
5089 sym = model. solution_variable_symbol
5190 ipc = _get_interpolation_from_discretization (discretization, sym)
91+ qrc = _get_quadrature_from_discretization (discretization, sym)
5292 dh = DofHandler (mesh)
5393 for name in discretization. subdomains
5494 add_subdomain! (dh, name, [ApproximationDescriptor (sym, ipc)])
@@ -61,11 +101,15 @@ function semidiscretize(model::SteadyDiffusionModel, discretization::FiniteEleme
61101 end
62102 close! (ch)
63103
64- return SteadyDiffusionFunction (
65- model. κ,
66- model. source,
104+ return AffineSteadyStateFunction (
105+ BilinearDiffusionIntegrator (
106+ model. κ,
107+ qrc,
108+ sym,
109+ ),
110+ model. source, # TODO qrc for source term
67111 dh,
68- ch
112+ ch,
69113 )
70114end
71115
@@ -109,9 +153,10 @@ function semidiscretize(split::ReactionDiffusionSplit{<:MonodomainModel}, discre
109153 return semidiscrete_ode
110154end
111155
112- function semidiscretize (model:: StructuralModel{<: QuasiStaticModel} , discretization:: FiniteElementDiscretization , mesh:: AbstractGrid )
156+ function semidiscretize (model:: QuasiStaticModel , discretization:: FiniteElementDiscretization , mesh:: AbstractGrid )
113157 sym = model. displacement_symbol
114158 ipc = _get_interpolation_from_discretization (discretization, sym)
159+ qrc = _get_quadrature_from_discretization (discretization, sym)
115160 dh = DofHandler (mesh)
116161 for name in discretization. subdomains
117162 add_subdomain! (dh, name, [ApproximationDescriptor (sym, ipc)])
@@ -124,11 +169,16 @@ function semidiscretize(model::StructuralModel{<:QuasiStaticModel}, discretizati
124169 end
125170 close! (ch)
126171
127- semidiscrete_problem = QuasiStaticNonlinearFunction (
172+ semidiscrete_problem = QuasiStaticFunction (
128173 dh,
129174 ch,
130- model. mechanical_model,
131- model. face_models
175+ NonlinearIntegrator (
176+ model,
177+ model. face_models,
178+ [sym],
179+ qrc,
180+ _get_facet_quadrature_from_discretization (discretization, sym),
181+ ),
132182 )
133183
134184 return semidiscrete_problem
0 commit comments