1+ abstract type ReconstructionOperator{FETypeR, O} <: AbstractFunctionOperator end
2+
3+ """
4+ $(TYPEDEF)
5+
6+ reconstruction operator: evaluates a reconstructed version of the finite element function.
7+
8+ FETypeR specifies the reconstruction space (needs to be defined for the finite element that it is applied to).
9+ O specifies the StandardFunctionOperator that shall be evaluated.
10+ """
11+ abstract type Reconstruct{FETypeR, O} <: ReconstructionOperator{FETypeR, O} end
12+
13+
14+ """
15+ WeightedReconstruct{FETypeR, O, w} <: Reconstruct{FETypeR, O}
16+
17+ Weighted reconstruction operator:
18+ evaluates a reconstructed version of a finite element function, multiplied by a weight function.
19+ **Warning**: This is a prototype and currently only works for the HDIVRT0{2} and HDIVBDM1{2} reconstruction of H1BR{2}.
20+
21+ # Parameters
22+ - `FETypeR`: The reconstruction finite element space type (target space for reconstruction).
23+ - `O`: The standard function operator to be evaluated (e.g., identity, gradient, etc.).
24+ - `w`: The type of the weight function (should be callable, e.g., a function or functor of type w(x)).
25+ """
26+ abstract type WeightedReconstruct{FETypeR, O, w} <: Reconstruct{FETypeR, O} end
27+
28+ weight_type (:: Type{<:WeightedReconstruct{FETypeR, O, w}} ) where {FETypeR, O, w} = w
29+
30+
131# ################# SPECIAL INTERPOLATORS ####################
232
333"""
@@ -69,18 +99,33 @@ abstract type ReconstructionDofs{FE1, FE2, AT} <: AbstractGridIntegerArray2D end
6999"""
70100$(TYPEDEF)
71101
102+ abstract grid component type that can be used to funnel reconstruction weights into the operator
103+ (default is 1)
104+ """
105+ abstract type ReconstructionWeights{AT} <: AbstractGridFloatArray2D end
106+
107+ """
108+ $(TYPEDEF)
109+
72110struct for storing information needed to evaluate a reconstruction operator
73111"""
74- struct ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG}
112+ struct ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG, F }
75113 FES:: FESpace{Tv, Ti, FE1, ON_CELLS}
76114 FER:: FESpace{Tv, Ti, FE2, ON_CELLS}
115+ xCoordinates:: Array{Tv, 2}
116+ xFaceNodes:: Adjacency{Ti}
77117 xFaceVolumes:: Array{Tv, 1}
78118 xFaceNormals:: Array{Tv, 2}
79119 xCellFaceOrientations:: Adjacency{Ti}
80120 xCellFaces:: Adjacency{Ti}
81121 interior_offset:: Int
82122 interior_ndofs:: Int
83123 interior_coefficients:: Matrix{Tv} # coefficients for interior basis functions are precomputed
124+ weight:: F
125+ end
126+
127+ function default_weight_function (x)
128+ return 1
84129end
85130
86131"""
@@ -90,7 +135,7 @@ generates a reconstruction handler
90135returns the local coefficients need to evaluate a reconstruction operator
91136of one finite element space into another
92137"""
93- function ReconstructionHandler (FES:: FESpace{Tv, Ti, FE1, APT} , FES_Reconst:: FESpace{Tv, Ti, FE2, APT} , AT, EG) where {Tv, Ti, FE1, FE2, APT}
138+ function ReconstructionHandler (FES:: FESpace{Tv, Ti, FE1, APT} , FES_Reconst:: FESpace{Tv, Ti, FE2, APT} , AT, EG, RT, weight = default_weight_function ) where {Tv, Ti, FE1, FE2, APT}
94139 xgrid = FES. xgrid
95140 interior_offset = interior_dofs_offset (AT, FE2, EG)
96141 interior_ndofs = get_ndofs (AT, FE2, EG) - interior_offset
@@ -100,11 +145,14 @@ function ReconstructionHandler(FES::FESpace{Tv, Ti, FE1, APT}, FES_Reconst::FESp
100145 interior_ndofs = 0
101146 coeffs = zeros (Tv, 0 , 0 )
102147 end
148+
103149 xFaceVolumes = xgrid[FaceVolumes]
104150 xFaceNormals = xgrid[FaceNormals]
151+ xCoordinates = xgrid[Coordinates]
152+ xFaceNodes = xgrid[FaceNodes]
105153 xCellFaceOrientations = dim_element (EG) == 2 ? xgrid[CellFaceSigns] : xgrid[CellFaceOrientations]
106154 xCellFaces = xgrid[CellFaces]
107- return ReconstructionHandler {Tv, Ti, FE1, FE2, AT, EG} (FES, FES_Reconst, xFaceVolumes, xFaceNormals, xCellFaceOrientations, xCellFaces, interior_offset, interior_ndofs, coeffs)
155+ return ReconstructionHandler {Tv, Ti, RT, FE1, FE2, AT, EG, typeof(weight) } (FES, FES_Reconst, xCoordinates, xFaceNodes, xFaceVolumes, xFaceNormals, xCellFaceOrientations, xCellFaces, interior_offset, interior_ndofs, coeffs, weight )
108156end
109157
110158"""
@@ -113,7 +161,7 @@ $(TYPEDSIGNATURES)
113161caller function to extract the coefficients of the reconstruction
114162on an item
115163"""
116- function get_rcoefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , item) where {Tv, Ti, FE1, FE2, AT, EG}
164+ function get_rcoefficients! (coefficients, RH:: ReconstructionHandler , item)
117165 boundary_coefficients! (coefficients, RH, item)
118166 for dof in 1 : size (coefficients, 1 ), k in 1 : RH. interior_ndofs
119167 coefficients[dof, RH. interior_offset + k] = RH. interior_coefficients[(dof - 1 ) * RH. interior_ndofs + k, item]
@@ -428,7 +476,7 @@ boundary_coefficients!(coefficients, RH::ReconstructionHandler, cell)
428476
429477generates the coefficients for the facial dofs of the reconstruction operator on the cell
430478"""
431- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, <:H1CR{ncomponents}, <:HDIVRT0{ncomponents}, <:ON_CELLS, EG} , cell) where {Tv, Ti, ncomponents, EG}
479+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, <:Reconstruct, <: H1CR{ncomponents}, <:HDIVRT0{ncomponents}, <:ON_CELLS, EG} , cell) where {Tv, Ti, ncomponents, EG}
432480 xFaceVolumes = RH. xFaceVolumes
433481 xFaceNormals = RH. xFaceNormals
434482 xCellFaces = RH. xCellFaces
@@ -446,59 +494,93 @@ end
446494
447495const _P1_INTO_BDM1_COEFFS = [- 1 // 12 , 1 // 12 ]
448496
449- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1BR{2} , FE2 <: HDIVBDM1{2} , AT <: ON_CELLS , EG <: Union{Triangle2D, Quadrilateral2D} }
497+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1BR{2} , FE2 <: HDIVBDM1{2} , AT <: ON_CELLS , EG <: Union{Triangle2D, Quadrilateral2D} }
450498 xFaceVolumes = RH. xFaceVolumes
451499 xFaceNormals = RH. xFaceNormals
452500 xCellFaceSigns = RH. xCellFaceOrientations
453501 xCellFaces = RH. xCellFaces
502+ xFaceNodes = RH. xFaceNodes
503+ xCoordinates = RH. xCoordinates
454504 face_rule = local_cellfacenodes (EG)
455505 nnodes = size (face_rule, 1 )
456506 nfaces = size (face_rule, 2 )
457507 node = 0
458508 face = 0
459509 BDM1_coeffs = _P1_INTO_BDM1_COEFFS
510+ weight = RH. weight
511+ xmid = zeros (Tv, 2 )
512+ w = ones (Tv, 2 )
460513 for f in 1 : nfaces
461514 face = xCellFaces[f, cell]
515+ x1 = view (xCoordinates, :, xFaceNodes[1 , face])
516+ x2 = view (xCoordinates, :, xFaceNodes[2 , face])
517+ xmid .= 0.5 * (x1 .+ x2)
518+ if xCellFaceSigns[f, cell] == - 1
519+ w[1 ] = weight (x2)
520+ w[2 ] = weight (x1)
521+ else
522+ w[1 ] = weight (x1)
523+ w[2 ] = weight (x2)
524+ end
525+ wmid = weight (xmid)
462526 for n in 1 : nnodes
463527 node = face_rule[n, f]
464528 for k in 1 : 2
465529 # RT0 reconstruction coefficients for P1 functions on reference element
466- coefficients[nfaces * (k - 1 ) + node, 2 * (f - 1 ) + 1 ] = 1 // 2 * xFaceVolumes[face] * xFaceNormals[k, face]
530+ coefficients[nfaces * (k - 1 ) + node, 2 * (f - 1 ) + 1 ] = xFaceVolumes[face] * ( 1 // 6 * w[n] + 1 // 3 * wmid) * xFaceNormals[k, face]
467531 # BDM1 reconstruction coefficients for P1 functions on reference element
468- coefficients[nfaces * (k - 1 ) + node, 2 * (f - 1 ) + 2 ] = BDM1_coeffs[n] * xFaceVolumes[face] * xFaceNormals[k, face] * xCellFaceSigns[f, cell]
532+ coefficients[nfaces * (k - 1 ) + node, 2 * (f - 1 ) + 2 ] = xFaceVolumes[face] * xFaceNormals[k, face] * xCellFaceSigns[f, cell] * (BDM1_coeffs[n] * w[n])
469533 end
470534 end
471535 # RT0 reconstruction coefficients for face bubbles on reference element
472- coefficients[nfaces * 2 + f, 2 * (f - 1 ) + 1 ] = xFaceVolumes[face]
536+ coefficients[nfaces * 2 + f, 2 * (f - 1 ) + 1 ] = xFaceVolumes[face] * wmid
473537 end
538+
474539 return nothing
475540end
476541
477- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1BR{2} , FE2 <: HDIVRT0{2} , AT <: ON_CELLS , EG <: Union{Triangle2D, Quadrilateral2D} }
542+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1BR{2} , FE2 <: HDIVRT0{2} , AT <: ON_CELLS , EG <: Union{Triangle2D, Quadrilateral2D} }
478543 xFaceVolumes = RH. xFaceVolumes
479544 xFaceNormals = RH. xFaceNormals
480545 xCellFaces = RH. xCellFaces
546+ xCellFaceSigns = RH. xCellFaceOrientations
547+ xFaceNodes = RH. xFaceNodes
548+ xCoordinates = RH. xCoordinates
481549 face_rule = local_cellfacenodes (EG)
482550 nnodes = size (face_rule, 1 )
483551 nfaces = size (face_rule, 2 )
484552 node = 0
485553 face = 0
554+ weight = RH. weight
555+ xmid = zeros (Tv, 2 )
556+ w = ones (Tv, 2 )
486557 for f in 1 : nfaces
487558 face = xCellFaces[f, cell]
559+ x1 = view (xCoordinates, :, xFaceNodes[1 , face])
560+ x2 = view (xCoordinates, :, xFaceNodes[2 , face])
561+ xmid .= 0.5 * (x1 .+ x2)
562+ if xCellFaceSigns[f, cell] == - 1
563+ w[1 ] = weight (x2)
564+ w[2 ] = weight (x1)
565+ else
566+ w[1 ] = weight (x1)
567+ w[2 ] = weight (x2)
568+ end
569+ wmid = weight (xmid)
488570 # reconstruction coefficients for P1 functions on reference element
489571 for n in 1 : nnodes
490572 node = face_rule[n, f]
491573 for k in 1 : 2
492- coefficients[nfaces * (k - 1 ) + node, f] = 1 // 2 * xFaceVolumes[face] * xFaceNormals[k, face]
574+ coefficients[nfaces * (k - 1 ) + node, f] = xFaceVolumes[face] * ( 1 // 6 * w[n] + 1 // 3 * wmid) * xFaceNormals[k, face]
493575 end
494576 end
495577 # reconstruction coefficients for face bubbles on reference element
496- coefficients[2 * nfaces + f, f] = xFaceVolumes[face]
578+ coefficients[2 * nfaces + f, f] = xFaceVolumes[face] * wmid
497579 end
498580 return nothing
499581end
500582
501- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1P2B{2, 2} , FE2 <: HDIVRT1{2} , AT <: ON_CELLS , EG <: Triangle2D }
583+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1P2B{2, 2} , FE2 <: HDIVRT1{2} , AT <: ON_CELLS , EG <: Triangle2D }
502584 xFaceVolumes = RH. xFaceVolumes
503585 xFaceNormals = RH. xFaceNormals
504586 xCellFaceSigns = RH. xCellFaceOrientations
@@ -529,7 +611,7 @@ function boundary_coefficients!(coefficients, RH::ReconstructionHandler{Tv, Ti,
529611 return nothing
530612end
531613
532- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1P2B{2, 2} , FE2 <: HDIVBDM2{2} , AT <: ON_CELLS , EG <: Triangle2D }
614+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1P2B{2, 2} , FE2 <: HDIVBDM2{2} , AT <: ON_CELLS , EG <: Triangle2D }
533615 xFaceVolumes = RH. xFaceVolumes
534616 xFaceNormals = RH. xFaceNormals
535617 xCellFaceSigns = RH. xCellFaceOrientations
@@ -567,7 +649,7 @@ function boundary_coefficients!(coefficients, RH::ReconstructionHandler{Tv, Ti,
567649end
568650
569651
570- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1BR{3} , FE2 <: HDIVRT0{3} , AT <: ON_CELLS , EG <: Tetrahedron3D }
652+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1BR{3} , FE2 <: HDIVRT0{3} , AT <: ON_CELLS , EG <: Tetrahedron3D }
571653 xFaceVolumes = RH. xFaceVolumes
572654 xFaceNormals = RH. xFaceNormals
573655 xCellFaces = RH. xCellFaces
592674
593675const _P1_INTO_BDM1_COEFFS_3D = [- 1 // 36 - 1 // 36 1 // 18 ; - 1 // 36 1 // 18 - 1 // 36 ; 1 // 18 - 1 // 36 - 1 // 36 ]
594676
595- function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG} , cell) where {Tv, Ti, FE1 <: H1BR{3} , FE2 <: HDIVBDM1{3} , AT <: ON_CELLS , EG <: Tetrahedron3D }
677+ function boundary_coefficients! (coefficients, RH:: ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG} , cell) where {Tv, Ti, RT <: Reconstruct , FE1 <: H1BR{3} , FE2 <: HDIVBDM1{3} , AT <: ON_CELLS , EG <: Tetrahedron3D }
596678 xFaceVolumes = RH. xFaceVolumes
597679 xFaceNormals = RH. xFaceNormals
598680 xCellFaces = RH. xCellFaces
0 commit comments