ngstSpaceKit.hermite
1from dataclasses import dataclass 2 3import ngsolve 4from ngsolve import ( 5 BBBND, 6 BBND, 7 BND, 8 H1, 9 L2, 10 TET, 11 TRIG, 12 IntegrationRule, 13 dx, 14) 15from ngsolve.utils import FacetFESpace 16from ngstrefftz import EmbeddedTrefftzFES, TrefftzEmbedding 17 18from ngstSpaceKit.diffops import del_x, del_y, del_z 19from ngstSpaceKit.mesh_properties import ( 20 throw_on_wrong_mesh_dimension, 21 throw_on_wrong_mesh_eltype, 22) 23 24 25@dataclass 26class HermiteDirichlet: 27 """ 28 Holds the dirichlet instructions for every type of dof in the `Hermite` space separately. 29 30 `deriv_z` is only used in the 3D case. 31 """ 32 33 vertex_value: str = "" 34 deriv_x: str = "" 35 deriv_y: str = "" 36 deriv_z: str = "" 37 38 @classmethod 39 def clamp(cls, bnd: str) -> "HermiteDirichlet": 40 """ 41 `bnd`: boundary where clamp conditions shall be set. 42 """ 43 return cls(vertex_value=bnd, deriv_x=bnd, deriv_y=bnd, deriv_z=bnd) 44 45 46def Hermite( 47 mesh: ngsolve.comp.Mesh, 48 dirichlet: str | HermiteDirichlet = "", 49 check_mesh: bool = True, 50 stats: dict | None = None, 51) -> EmbeddedTrefftzFES: 52 r""" 53 The Hermite element is implemented for 2D and 3D on triangles and tetrahedrons. 54 55 `check_mesh`: test, if the `mesh` is compatible with this space 56 57 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 58 59 # Raises 60 - ValueError, if the mesh is neither 2D nor 3D 61 - ValueError, if the mesh is neither triangular nor tetrahedral 62 63 # Conforming Trefftz Formulation for 2D 64 - $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$ 65 - $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^3 \times \mathbb{P}^{0}(\mathcal{T}_h)$ 66 - \begin{align} 67 \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\\\ 68 &\sum_{p \text{ is vertex}} v_h(p) z_h^\text{value}(p) 69 + \sum_{p \text{ is vertex}} \partial_x v_h(p) z_h^\text{x}(p) \\\\ 70 &+ \sum_{p \text{ is vertex}} \partial_y v_h(p) z_h^\text{y}(p) 71 + \sum_{m \text{ is element-midpoint}} v_h(m) z_h^\text{mid}(m), \\\\ 72 \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{mid})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\\\ 73 &\sum_{p \text{ is vertex}} y_h^\text{value}(p) z_h^\text{value}(p) 74 + \sum_{p \text{ is vertex}} y_h^\text{x}(p) z_h^\text{x}(p) \\\\ 75 &+ \sum_{p \text{ is vertex}} y_h^\text{y}(p) z_h^\text{y}(p) 76 + \sum_{m \text{ is element-midpoint}} y_h^\text{mid}(m) z_h^\text{mid}(m) 77 \end{align} 78 """ 79 if check_mesh: 80 throw_on_wrong_mesh_dimension(mesh, [2, 3]) 81 throw_on_wrong_mesh_eltype(mesh, [TRIG, TET]) 82 83 dirichlet_struct = ( 84 HermiteDirichlet(vertex_value=dirichlet) 85 if type(dirichlet) is str 86 else dirichlet 87 ) 88 assert type(dirichlet_struct) is HermiteDirichlet 89 90 if mesh.dim == 2: 91 return Hermite2D( 92 mesh, 93 dirichlet_struct, 94 check_mesh=False, 95 stats=stats, 96 ) 97 else: 98 return Hermite3D( 99 mesh, 100 dirichlet_struct, 101 check_mesh=False, 102 stats=stats, 103 ) 104 105 106def Hermite2D( 107 mesh: ngsolve.comp.Mesh, 108 dirichlet: HermiteDirichlet, 109 check_mesh: bool = True, 110 stats: dict | None = None, 111) -> EmbeddedTrefftzFES: 112 """ 113 Implementation of the Hermite element in 2D 114 115 `check_mesh`: test, if the `mesh` is compatible with this space 116 117 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 118 119 # Raises 120 - ValueError, if the mesh is not 2D 121 - ValueError, if the mesh is not triangular 122 """ 123 if check_mesh: 124 throw_on_wrong_mesh_dimension(mesh, 2) 125 throw_on_wrong_mesh_eltype(mesh, TRIG) 126 127 fes = L2(mesh, order=3) 128 vertex_value_space = H1(mesh, order=1, dirichlet=dirichlet.vertex_value) 129 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_x) 130 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_y) 131 midpoint_value_space = L2(mesh, order=0) 132 133 conformity_space = ( 134 vertex_value_space 135 * deriv_x_value_space 136 * deriv_y_value_space 137 * midpoint_value_space 138 ) 139 140 u = fes.TrialFunction() 141 (u_, u_dx, u_dy, u_m) = conformity_space.TrialFunction() 142 (v_, v_dx, v_dy, v_m) = conformity_space.TestFunction() 143 144 dVertex = dx(element_vb=BBND) 145 146 midpoint_intrule = IntegrationRule(points=[(1 / 3, 1 / 3)], weights=[1]) 147 dMidpoint = dx(intrules={TRIG: midpoint_intrule}) 148 149 cop_lhs = ( 150 u * v_ * dVertex 151 + del_x(u) * v_dx * dVertex 152 + del_y(u) * v_dy * dVertex 153 + u * v_m * dMidpoint 154 ) 155 cop_rhs = ( 156 u_ * v_ * dVertex 157 + u_dx * v_dx * dVertex 158 + u_dy * v_dy * dVertex 159 + u_m * v_m * dVertex 160 ) 161 162 embedding = TrefftzEmbedding( 163 cop=cop_lhs, 164 crhs=cop_rhs, 165 ndof_trefftz=0, 166 stats=stats, 167 ) 168 169 hermite = EmbeddedTrefftzFES(embedding) 170 return hermite 171 172 173def Hermite3D( 174 mesh: ngsolve.comp.Mesh, 175 dirichlet: HermiteDirichlet, 176 check_mesh: bool = True, 177 stats: dict | None = None, 178) -> EmbeddedTrefftzFES: 179 """ 180 Implementation of the Hermite element in 3D 181 182 `check_mesh`: test, if the `mesh` is compatible with this space 183 184 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 185 186 # Raises 187 - ValueError, if the mesh is not 3D 188 - ValueError, if the mesh is not tetrahedral 189 """ 190 if check_mesh: 191 throw_on_wrong_mesh_dimension(mesh, 3) 192 throw_on_wrong_mesh_eltype(mesh, TET) 193 194 fes = L2(mesh, order=3) 195 vertex_value_space = H1(mesh, order=1, dirichlet=dirichlet.vertex_value) 196 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_x) 197 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_y) 198 deriv_z_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_z) 199 midpoint_value_space = FacetFESpace(mesh, order=0) 200 201 conformity_space = ( 202 vertex_value_space 203 * deriv_x_value_space 204 * deriv_y_value_space 205 * deriv_z_value_space 206 * midpoint_value_space 207 ) 208 209 u = fes.TrialFunction() 210 (u_, u_dx, u_dy, u_dz, u_m) = conformity_space.TrialFunction() 211 (v_, v_dx, v_dy, v_dz, v_m) = conformity_space.TestFunction() 212 213 dVertex = dx(element_vb=BBBND) 214 215 midpoint_intrule = IntegrationRule(points=[(1 / 3, 1 / 3)], weights=[1]) 216 dMidpoint = dx(intrules={TRIG: midpoint_intrule}, element_vb=BND) 217 218 cop_lhs = ( 219 u * v_ * dVertex 220 + del_x(u) * v_dx * dVertex 221 + del_y(u) * v_dy * dVertex 222 + del_z(u) * v_dz * dVertex 223 + u * v_m * dMidpoint 224 ) 225 cop_rhs = ( 226 u_ * v_ * dVertex 227 + u_dx * v_dx * dVertex 228 + u_dy * v_dy * dVertex 229 + u_dz * v_dz * dVertex 230 + u_m * v_m * dVertex 231 ) 232 233 embedding = TrefftzEmbedding( 234 cop=cop_lhs, 235 crhs=cop_rhs, 236 ndof_trefftz=0, 237 stats=stats, 238 ) 239 240 hermite = EmbeddedTrefftzFES(embedding) 241 return hermite
@dataclass
class
HermiteDirichlet:
26@dataclass 27class HermiteDirichlet: 28 """ 29 Holds the dirichlet instructions for every type of dof in the `Hermite` space separately. 30 31 `deriv_z` is only used in the 3D case. 32 """ 33 34 vertex_value: str = "" 35 deriv_x: str = "" 36 deriv_y: str = "" 37 deriv_z: str = "" 38 39 @classmethod 40 def clamp(cls, bnd: str) -> "HermiteDirichlet": 41 """ 42 `bnd`: boundary where clamp conditions shall be set. 43 """ 44 return cls(vertex_value=bnd, deriv_x=bnd, deriv_y=bnd, deriv_z=bnd)
Holds the dirichlet instructions for every type of dof in the Hermite space separately.
deriv_z is only used in the 3D case.
def
Hermite( mesh: ngsolve.comp.Mesh, dirichlet: str | HermiteDirichlet = '', check_mesh: bool = True, stats: dict | None = None) -> ngstrefftz.EmbeddedTrefftzFES:
47def Hermite( 48 mesh: ngsolve.comp.Mesh, 49 dirichlet: str | HermiteDirichlet = "", 50 check_mesh: bool = True, 51 stats: dict | None = None, 52) -> EmbeddedTrefftzFES: 53 r""" 54 The Hermite element is implemented for 2D and 3D on triangles and tetrahedrons. 55 56 `check_mesh`: test, if the `mesh` is compatible with this space 57 58 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 59 60 # Raises 61 - ValueError, if the mesh is neither 2D nor 3D 62 - ValueError, if the mesh is neither triangular nor tetrahedral 63 64 # Conforming Trefftz Formulation for 2D 65 - $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$ 66 - $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^3 \times \mathbb{P}^{0}(\mathcal{T}_h)$ 67 - \begin{align} 68 \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\\\ 69 &\sum_{p \text{ is vertex}} v_h(p) z_h^\text{value}(p) 70 + \sum_{p \text{ is vertex}} \partial_x v_h(p) z_h^\text{x}(p) \\\\ 71 &+ \sum_{p \text{ is vertex}} \partial_y v_h(p) z_h^\text{y}(p) 72 + \sum_{m \text{ is element-midpoint}} v_h(m) z_h^\text{mid}(m), \\\\ 73 \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{mid})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\\\ 74 &\sum_{p \text{ is vertex}} y_h^\text{value}(p) z_h^\text{value}(p) 75 + \sum_{p \text{ is vertex}} y_h^\text{x}(p) z_h^\text{x}(p) \\\\ 76 &+ \sum_{p \text{ is vertex}} y_h^\text{y}(p) z_h^\text{y}(p) 77 + \sum_{m \text{ is element-midpoint}} y_h^\text{mid}(m) z_h^\text{mid}(m) 78 \end{align} 79 """ 80 if check_mesh: 81 throw_on_wrong_mesh_dimension(mesh, [2, 3]) 82 throw_on_wrong_mesh_eltype(mesh, [TRIG, TET]) 83 84 dirichlet_struct = ( 85 HermiteDirichlet(vertex_value=dirichlet) 86 if type(dirichlet) is str 87 else dirichlet 88 ) 89 assert type(dirichlet_struct) is HermiteDirichlet 90 91 if mesh.dim == 2: 92 return Hermite2D( 93 mesh, 94 dirichlet_struct, 95 check_mesh=False, 96 stats=stats, 97 ) 98 else: 99 return Hermite3D( 100 mesh, 101 dirichlet_struct, 102 check_mesh=False, 103 stats=stats, 104 )
The Hermite element is implemented for 2D and 3D on triangles and tetrahedrons.
check_mesh: test, if the mesh is compatible with this space
stats: use the stats flag of the TrefftzEmbeddin method
Raises
- ValueError, if the mesh is neither 2D nor 3D
- ValueError, if the mesh is neither triangular nor tetrahedral
Conforming Trefftz Formulation for 2D
- $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$
- $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^3 \times \mathbb{P}^{0}(\mathcal{T}_h)$
- \begin{align} \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\ &\sum_{p \text{ is vertex}} v_h(p) z_h^\text{value}(p) + \sum_{p \text{ is vertex}} \partial_x v_h(p) z_h^\text{x}(p) \\ &+ \sum_{p \text{ is vertex}} \partial_y v_h(p) z_h^\text{y}(p) + \sum_{m \text{ is element-midpoint}} v_h(m) z_h^\text{mid}(m), \\ \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{mid})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{mid})) := \\ &\sum_{p \text{ is vertex}} y_h^\text{value}(p) z_h^\text{value}(p) + \sum_{p \text{ is vertex}} y_h^\text{x}(p) z_h^\text{x}(p) \\ &+ \sum_{p \text{ is vertex}} y_h^\text{y}(p) z_h^\text{y}(p) + \sum_{m \text{ is element-midpoint}} y_h^\text{mid}(m) z_h^\text{mid}(m) \end{align}
def
Hermite2D( mesh: ngsolve.comp.Mesh, dirichlet: HermiteDirichlet, check_mesh: bool = True, stats: dict | None = None) -> ngstrefftz.EmbeddedTrefftzFES:
107def Hermite2D( 108 mesh: ngsolve.comp.Mesh, 109 dirichlet: HermiteDirichlet, 110 check_mesh: bool = True, 111 stats: dict | None = None, 112) -> EmbeddedTrefftzFES: 113 """ 114 Implementation of the Hermite element in 2D 115 116 `check_mesh`: test, if the `mesh` is compatible with this space 117 118 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 119 120 # Raises 121 - ValueError, if the mesh is not 2D 122 - ValueError, if the mesh is not triangular 123 """ 124 if check_mesh: 125 throw_on_wrong_mesh_dimension(mesh, 2) 126 throw_on_wrong_mesh_eltype(mesh, TRIG) 127 128 fes = L2(mesh, order=3) 129 vertex_value_space = H1(mesh, order=1, dirichlet=dirichlet.vertex_value) 130 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_x) 131 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_y) 132 midpoint_value_space = L2(mesh, order=0) 133 134 conformity_space = ( 135 vertex_value_space 136 * deriv_x_value_space 137 * deriv_y_value_space 138 * midpoint_value_space 139 ) 140 141 u = fes.TrialFunction() 142 (u_, u_dx, u_dy, u_m) = conformity_space.TrialFunction() 143 (v_, v_dx, v_dy, v_m) = conformity_space.TestFunction() 144 145 dVertex = dx(element_vb=BBND) 146 147 midpoint_intrule = IntegrationRule(points=[(1 / 3, 1 / 3)], weights=[1]) 148 dMidpoint = dx(intrules={TRIG: midpoint_intrule}) 149 150 cop_lhs = ( 151 u * v_ * dVertex 152 + del_x(u) * v_dx * dVertex 153 + del_y(u) * v_dy * dVertex 154 + u * v_m * dMidpoint 155 ) 156 cop_rhs = ( 157 u_ * v_ * dVertex 158 + u_dx * v_dx * dVertex 159 + u_dy * v_dy * dVertex 160 + u_m * v_m * dVertex 161 ) 162 163 embedding = TrefftzEmbedding( 164 cop=cop_lhs, 165 crhs=cop_rhs, 166 ndof_trefftz=0, 167 stats=stats, 168 ) 169 170 hermite = EmbeddedTrefftzFES(embedding) 171 return hermite
Implementation of the Hermite element in 2D
check_mesh: test, if the mesh is compatible with this space
stats: use the stats flag of the TrefftzEmbeddin method
Raises
- ValueError, if the mesh is not 2D
- ValueError, if the mesh is not triangular
def
Hermite3D( mesh: ngsolve.comp.Mesh, dirichlet: HermiteDirichlet, check_mesh: bool = True, stats: dict | None = None) -> ngstrefftz.EmbeddedTrefftzFES:
174def Hermite3D( 175 mesh: ngsolve.comp.Mesh, 176 dirichlet: HermiteDirichlet, 177 check_mesh: bool = True, 178 stats: dict | None = None, 179) -> EmbeddedTrefftzFES: 180 """ 181 Implementation of the Hermite element in 3D 182 183 `check_mesh`: test, if the `mesh` is compatible with this space 184 185 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 186 187 # Raises 188 - ValueError, if the mesh is not 3D 189 - ValueError, if the mesh is not tetrahedral 190 """ 191 if check_mesh: 192 throw_on_wrong_mesh_dimension(mesh, 3) 193 throw_on_wrong_mesh_eltype(mesh, TET) 194 195 fes = L2(mesh, order=3) 196 vertex_value_space = H1(mesh, order=1, dirichlet=dirichlet.vertex_value) 197 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_x) 198 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_y) 199 deriv_z_value_space = H1(mesh, order=1, dirichlet=dirichlet.deriv_z) 200 midpoint_value_space = FacetFESpace(mesh, order=0) 201 202 conformity_space = ( 203 vertex_value_space 204 * deriv_x_value_space 205 * deriv_y_value_space 206 * deriv_z_value_space 207 * midpoint_value_space 208 ) 209 210 u = fes.TrialFunction() 211 (u_, u_dx, u_dy, u_dz, u_m) = conformity_space.TrialFunction() 212 (v_, v_dx, v_dy, v_dz, v_m) = conformity_space.TestFunction() 213 214 dVertex = dx(element_vb=BBBND) 215 216 midpoint_intrule = IntegrationRule(points=[(1 / 3, 1 / 3)], weights=[1]) 217 dMidpoint = dx(intrules={TRIG: midpoint_intrule}, element_vb=BND) 218 219 cop_lhs = ( 220 u * v_ * dVertex 221 + del_x(u) * v_dx * dVertex 222 + del_y(u) * v_dy * dVertex 223 + del_z(u) * v_dz * dVertex 224 + u * v_m * dMidpoint 225 ) 226 cop_rhs = ( 227 u_ * v_ * dVertex 228 + u_dx * v_dx * dVertex 229 + u_dy * v_dy * dVertex 230 + u_dz * v_dz * dVertex 231 + u_m * v_m * dVertex 232 ) 233 234 embedding = TrefftzEmbedding( 235 cop=cop_lhs, 236 crhs=cop_rhs, 237 ndof_trefftz=0, 238 stats=stats, 239 ) 240 241 hermite = EmbeddedTrefftzFES(embedding) 242 return hermite
Implementation of the Hermite element in 3D
check_mesh: test, if the mesh is compatible with this space
stats: use the stats flag of the TrefftzEmbeddin method
Raises
- ValueError, if the mesh is not 3D
- ValueError, if the mesh is not tetrahedral