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
+
1
31
# ################# SPECIAL INTERPOLATORS ####################
2
32
3
33
"""
@@ -69,18 +99,33 @@ abstract type ReconstructionDofs{FE1, FE2, AT} <: AbstractGridIntegerArray2D end
69
99
"""
70
100
$(TYPEDEF)
71
101
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
+
72
110
struct for storing information needed to evaluate a reconstruction operator
73
111
"""
74
- struct ReconstructionHandler{Tv, Ti, FE1, FE2, AT, EG}
112
+ struct ReconstructionHandler{Tv, Ti, RT, FE1, FE2, AT, EG, F }
75
113
FES:: FESpace{Tv, Ti, FE1, ON_CELLS}
76
114
FER:: FESpace{Tv, Ti, FE2, ON_CELLS}
115
+ xCoordinates:: Array{Tv, 2}
116
+ xFaceNodes:: Adjacency{Ti}
77
117
xFaceVolumes:: Array{Tv, 1}
78
118
xFaceNormals:: Array{Tv, 2}
79
119
xCellFaceOrientations:: Adjacency{Ti}
80
120
xCellFaces:: Adjacency{Ti}
81
121
interior_offset:: Int
82
122
interior_ndofs:: Int
83
123
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
84
129
end
85
130
86
131
"""
@@ -90,7 +135,7 @@ generates a reconstruction handler
90
135
returns the local coefficients need to evaluate a reconstruction operator
91
136
of one finite element space into another
92
137
"""
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}
94
139
xgrid = FES. xgrid
95
140
interior_offset = interior_dofs_offset (AT, FE2, EG)
96
141
interior_ndofs = get_ndofs (AT, FE2, EG) - interior_offset
@@ -100,11 +145,14 @@ function ReconstructionHandler(FES::FESpace{Tv, Ti, FE1, APT}, FES_Reconst::FESp
100
145
interior_ndofs = 0
101
146
coeffs = zeros (Tv, 0 , 0 )
102
147
end
148
+
103
149
xFaceVolumes = xgrid[FaceVolumes]
104
150
xFaceNormals = xgrid[FaceNormals]
151
+ xCoordinates = xgrid[Coordinates]
152
+ xFaceNodes = xgrid[FaceNodes]
105
153
xCellFaceOrientations = dim_element (EG) == 2 ? xgrid[CellFaceSigns] : xgrid[CellFaceOrientations]
106
154
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 )
108
156
end
109
157
110
158
"""
@@ -113,7 +161,7 @@ $(TYPEDSIGNATURES)
113
161
caller function to extract the coefficients of the reconstruction
114
162
on an item
115
163
"""
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)
117
165
boundary_coefficients! (coefficients, RH, item)
118
166
for dof in 1 : size (coefficients, 1 ), k in 1 : RH. interior_ndofs
119
167
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)
428
476
429
477
generates the coefficients for the facial dofs of the reconstruction operator on the cell
430
478
"""
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}
432
480
xFaceVolumes = RH. xFaceVolumes
433
481
xFaceNormals = RH. xFaceNormals
434
482
xCellFaces = RH. xCellFaces
@@ -446,59 +494,93 @@ end
446
494
447
495
const _P1_INTO_BDM1_COEFFS = [- 1 // 12 , 1 // 12 ]
448
496
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} }
450
498
xFaceVolumes = RH. xFaceVolumes
451
499
xFaceNormals = RH. xFaceNormals
452
500
xCellFaceSigns = RH. xCellFaceOrientations
453
501
xCellFaces = RH. xCellFaces
502
+ xFaceNodes = RH. xFaceNodes
503
+ xCoordinates = RH. xCoordinates
454
504
face_rule = local_cellfacenodes (EG)
455
505
nnodes = size (face_rule, 1 )
456
506
nfaces = size (face_rule, 2 )
457
507
node = 0
458
508
face = 0
459
509
BDM1_coeffs = _P1_INTO_BDM1_COEFFS
510
+ weight = RH. weight
511
+ xmid = zeros (Tv, 2 )
512
+ w = ones (Tv, 2 )
460
513
for f in 1 : nfaces
461
514
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)
462
526
for n in 1 : nnodes
463
527
node = face_rule[n, f]
464
528
for k in 1 : 2
465
529
# 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]
467
531
# 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])
469
533
end
470
534
end
471
535
# 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
473
537
end
538
+
474
539
return nothing
475
540
end
476
541
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} }
478
543
xFaceVolumes = RH. xFaceVolumes
479
544
xFaceNormals = RH. xFaceNormals
480
545
xCellFaces = RH. xCellFaces
546
+ xCellFaceSigns = RH. xCellFaceOrientations
547
+ xFaceNodes = RH. xFaceNodes
548
+ xCoordinates = RH. xCoordinates
481
549
face_rule = local_cellfacenodes (EG)
482
550
nnodes = size (face_rule, 1 )
483
551
nfaces = size (face_rule, 2 )
484
552
node = 0
485
553
face = 0
554
+ weight = RH. weight
555
+ xmid = zeros (Tv, 2 )
556
+ w = ones (Tv, 2 )
486
557
for f in 1 : nfaces
487
558
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)
488
570
# reconstruction coefficients for P1 functions on reference element
489
571
for n in 1 : nnodes
490
572
node = face_rule[n, f]
491
573
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]
493
575
end
494
576
end
495
577
# 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
497
579
end
498
580
return nothing
499
581
end
500
582
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 }
502
584
xFaceVolumes = RH. xFaceVolumes
503
585
xFaceNormals = RH. xFaceNormals
504
586
xCellFaceSigns = RH. xCellFaceOrientations
@@ -529,7 +611,7 @@ function boundary_coefficients!(coefficients, RH::ReconstructionHandler{Tv, Ti,
529
611
return nothing
530
612
end
531
613
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 }
533
615
xFaceVolumes = RH. xFaceVolumes
534
616
xFaceNormals = RH. xFaceNormals
535
617
xCellFaceSigns = RH. xCellFaceOrientations
@@ -567,7 +649,7 @@ function boundary_coefficients!(coefficients, RH::ReconstructionHandler{Tv, Ti,
567
649
end
568
650
569
651
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 }
571
653
xFaceVolumes = RH. xFaceVolumes
572
654
xFaceNormals = RH. xFaceNormals
573
655
xCellFaces = RH. xCellFaces
592
674
593
675
const _P1_INTO_BDM1_COEFFS_3D = [- 1 // 36 - 1 // 36 1 // 18 ; - 1 // 36 1 // 18 - 1 // 36 ; 1 // 18 - 1 // 36 - 1 // 36 ]
594
676
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 }
596
678
xFaceVolumes = RH. xFaceVolumes
597
679
xFaceNormals = RH. xFaceNormals
598
680
xCellFaces = RH. xCellFaces
0 commit comments