ngstSpaceKit.bfs
1from dataclasses import dataclass 2 3import ngsolve 4from ngsolve import ( 5 BBND, 6 H1, 7 L2, 8 QUAD, 9 dx, 10) 11from ngstrefftz import EmbeddedTrefftzFES, L2EmbTrefftzFESpace, TrefftzEmbedding 12 13from ngstSpaceKit.diffops import del_x, del_xy, del_y 14from ngstSpaceKit.mesh_properties import ( 15 throw_on_wrong_mesh_dimension, 16 throw_on_wrong_mesh_eltype, 17) 18 19 20@dataclass 21class BFSDirichlet: 22 """ 23 Holds the dirichlet instructions for every type of dof in the `BFS` space separately. 24 """ 25 26 vertex_value: str = "" 27 deriv_x: str = "" 28 deriv_y: str = "" 29 deriv_xy: str = "" 30 31 @classmethod 32 def clamp_weak(cls, bnd: str) -> "BFSDirichlet": 33 """ 34 `bnd`: boundary where (weak) clamp conditions shall be set. 35 36 By the nature of the `BFS` space, the clamp conditions will not apply to the whole boundary, 37 but only at certain points along the boundary. Further action is necessary to completely enforce clamp conditions. 38 """ 39 return cls(vertex_value=bnd, deriv_x=bnd, deriv_y=bnd) 40 41 42def BognerFoxSchmitt( 43 mesh: ngsolve.comp.Mesh, 44 dirichlet: str | BFSDirichlet = "", 45 check_mesh: bool = True, 46 stats: dict | None = None, 47) -> L2EmbTrefftzFESpace: 48 r""" 49 This element is for quads. 50 51 `dirichlet`: if you provide a string, it will set dirichlet conditions only for vertex value dofs. For more control, use `BFSDirichlet`. 52 53 `check_mesh`: test, if the `mesh` is compatible with this space 54 55 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 56 57 # Raises 58 - ValueError, if the mesh is not 2D 59 - ValueError, if the mesh is not rectangular 60 61 # Conforming Trefftz Formulation 62 - $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$ 63 - $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^4$ 64 - \begin{align} 65 \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\\\ 66 &\sum_{p \text{ is vertex}} v_h(p) z_h^\text{value}(p) 67 + \sum_{p \text{ is vertex}} \partial_x v_h(p) z_h^\text{x}(p) \\\\ 68 &+ \sum_{p \text{ is vertex}} \partial_y v_h(p) z_h^\text{y}(p) 69 + \sum_{p \text{ is vertex}} \partial_{xy} v_h(p) z_h^\text{xy}(p), \\\\ 70 \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{xy})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\\\ 71 &\sum_{p \text{ is vertex}} y_h^\text{value}(p) z_h^\text{value}(p) 72 + \sum_{p \text{ is vertex}} y_h^\text{x}(p) z_h^\text{x}(p) \\\\ 73 &+ \sum_{p \text{ is vertex}} y_h^\text{y}(p) z_h^\text{y}(p) 74 + \sum_{p \text{ is vertex}} y_h^\text{xy}(p) z_h^\text{xy}(p) 75 \end{align} 76 """ 77 if check_mesh: 78 throw_on_wrong_mesh_dimension(mesh, 2) 79 throw_on_wrong_mesh_eltype(mesh, QUAD) 80 81 dirichlet_struct = ( 82 BFSDirichlet(vertex_value=dirichlet) 83 if type(dirichlet) is str 84 else dirichlet 85 ) 86 assert type(dirichlet_struct) is BFSDirichlet 87 88 fes = L2(mesh, order=3) 89 vertex_value_space = H1( 90 mesh, order=1, dirichlet=dirichlet_struct.vertex_value 91 ) 92 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet_struct.deriv_x) 93 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet_struct.deriv_y) 94 deriv_xy_value_space = H1( 95 mesh, order=1, dirichlet=dirichlet_struct.deriv_xy 96 ) 97 98 conformity_space = ( 99 vertex_value_space 100 * deriv_x_value_space 101 * deriv_y_value_space 102 * deriv_xy_value_space 103 ) 104 105 u = fes.TrialFunction() 106 (u_, u_dx, u_dy, u_dxy) = conformity_space.TrialFunction() 107 (v_, v_dx, v_dy, v_dxy) = conformity_space.TestFunction() 108 109 dVertex = dx(element_vb=BBND) 110 111 cop_lhs = ( 112 u * v_ * dVertex 113 + del_x(u) * v_dx * dVertex 114 + del_y(u) * v_dy * dVertex 115 + del_xy(u) * v_dxy * dVertex 116 ) 117 cop_rhs = ( 118 u_ * v_ * dVertex 119 + u_dx * v_dx * dVertex 120 + u_dy * v_dy * dVertex 121 + u_dxy * v_dxy * dVertex 122 ) 123 124 embedding = TrefftzEmbedding( 125 cop=cop_lhs, 126 crhs=cop_rhs, 127 ndof_trefftz=0, 128 stats=stats, 129 ) 130 131 bfs = EmbeddedTrefftzFES(embedding) 132 assert type(bfs) is L2EmbTrefftzFESpace, ( 133 "The bfs space should always be an L2EmbTrefftzFESpace" 134 ) 135 136 return bfs
@dataclass
class
BFSDirichlet:
21@dataclass 22class BFSDirichlet: 23 """ 24 Holds the dirichlet instructions for every type of dof in the `BFS` space separately. 25 """ 26 27 vertex_value: str = "" 28 deriv_x: str = "" 29 deriv_y: str = "" 30 deriv_xy: str = "" 31 32 @classmethod 33 def clamp_weak(cls, bnd: str) -> "BFSDirichlet": 34 """ 35 `bnd`: boundary where (weak) clamp conditions shall be set. 36 37 By the nature of the `BFS` space, the clamp conditions will not apply to the whole boundary, 38 but only at certain points along the boundary. Further action is necessary to completely enforce clamp conditions. 39 """ 40 return cls(vertex_value=bnd, deriv_x=bnd, deriv_y=bnd)
Holds the dirichlet instructions for every type of dof in the BFS space separately.
32 @classmethod 33 def clamp_weak(cls, bnd: str) -> "BFSDirichlet": 34 """ 35 `bnd`: boundary where (weak) clamp conditions shall be set. 36 37 By the nature of the `BFS` space, the clamp conditions will not apply to the whole boundary, 38 but only at certain points along the boundary. Further action is necessary to completely enforce clamp conditions. 39 """ 40 return cls(vertex_value=bnd, deriv_x=bnd, deriv_y=bnd)
bnd: boundary where (weak) clamp conditions shall be set.
By the nature of the BFS space, the clamp conditions will not apply to the whole boundary,
but only at certain points along the boundary. Further action is necessary to completely enforce clamp conditions.
def
BognerFoxSchmitt( mesh: ngsolve.comp.Mesh, dirichlet: str | BFSDirichlet = '', check_mesh: bool = True, stats: dict | None = None) -> ngstrefftz.L2EmbTrefftzFESpace:
43def BognerFoxSchmitt( 44 mesh: ngsolve.comp.Mesh, 45 dirichlet: str | BFSDirichlet = "", 46 check_mesh: bool = True, 47 stats: dict | None = None, 48) -> L2EmbTrefftzFESpace: 49 r""" 50 This element is for quads. 51 52 `dirichlet`: if you provide a string, it will set dirichlet conditions only for vertex value dofs. For more control, use `BFSDirichlet`. 53 54 `check_mesh`: test, if the `mesh` is compatible with this space 55 56 `stats`: use the `stats` flag of the `TrefftzEmbeddin` method 57 58 # Raises 59 - ValueError, if the mesh is not 2D 60 - ValueError, if the mesh is not rectangular 61 62 # Conforming Trefftz Formulation 63 - $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$ 64 - $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^4$ 65 - \begin{align} 66 \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\\\ 67 &\sum_{p \text{ is vertex}} v_h(p) z_h^\text{value}(p) 68 + \sum_{p \text{ is vertex}} \partial_x v_h(p) z_h^\text{x}(p) \\\\ 69 &+ \sum_{p \text{ is vertex}} \partial_y v_h(p) z_h^\text{y}(p) 70 + \sum_{p \text{ is vertex}} \partial_{xy} v_h(p) z_h^\text{xy}(p), \\\\ 71 \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{xy})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\\\ 72 &\sum_{p \text{ is vertex}} y_h^\text{value}(p) z_h^\text{value}(p) 73 + \sum_{p \text{ is vertex}} y_h^\text{x}(p) z_h^\text{x}(p) \\\\ 74 &+ \sum_{p \text{ is vertex}} y_h^\text{y}(p) z_h^\text{y}(p) 75 + \sum_{p \text{ is vertex}} y_h^\text{xy}(p) z_h^\text{xy}(p) 76 \end{align} 77 """ 78 if check_mesh: 79 throw_on_wrong_mesh_dimension(mesh, 2) 80 throw_on_wrong_mesh_eltype(mesh, QUAD) 81 82 dirichlet_struct = ( 83 BFSDirichlet(vertex_value=dirichlet) 84 if type(dirichlet) is str 85 else dirichlet 86 ) 87 assert type(dirichlet_struct) is BFSDirichlet 88 89 fes = L2(mesh, order=3) 90 vertex_value_space = H1( 91 mesh, order=1, dirichlet=dirichlet_struct.vertex_value 92 ) 93 deriv_x_value_space = H1(mesh, order=1, dirichlet=dirichlet_struct.deriv_x) 94 deriv_y_value_space = H1(mesh, order=1, dirichlet=dirichlet_struct.deriv_y) 95 deriv_xy_value_space = H1( 96 mesh, order=1, dirichlet=dirichlet_struct.deriv_xy 97 ) 98 99 conformity_space = ( 100 vertex_value_space 101 * deriv_x_value_space 102 * deriv_y_value_space 103 * deriv_xy_value_space 104 ) 105 106 u = fes.TrialFunction() 107 (u_, u_dx, u_dy, u_dxy) = conformity_space.TrialFunction() 108 (v_, v_dx, v_dy, v_dxy) = conformity_space.TestFunction() 109 110 dVertex = dx(element_vb=BBND) 111 112 cop_lhs = ( 113 u * v_ * dVertex 114 + del_x(u) * v_dx * dVertex 115 + del_y(u) * v_dy * dVertex 116 + del_xy(u) * v_dxy * dVertex 117 ) 118 cop_rhs = ( 119 u_ * v_ * dVertex 120 + u_dx * v_dx * dVertex 121 + u_dy * v_dy * dVertex 122 + u_dxy * v_dxy * dVertex 123 ) 124 125 embedding = TrefftzEmbedding( 126 cop=cop_lhs, 127 crhs=cop_rhs, 128 ndof_trefftz=0, 129 stats=stats, 130 ) 131 132 bfs = EmbeddedTrefftzFES(embedding) 133 assert type(bfs) is L2EmbTrefftzFESpace, ( 134 "The bfs space should always be an L2EmbTrefftzFESpace" 135 ) 136 137 return bfs
This element is for quads.
dirichlet: if you provide a string, it will set dirichlet conditions only for vertex value dofs. For more control, use BFSDirichlet.
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 rectangular
Conforming Trefftz Formulation
- $\mathbb{V}_h := \mathbb{P}^{3, \text{disc}}(\mathcal{T}_h)$
- $\mathbb{Z}_h := [\mathbb{P}^{1}(\mathcal{T}_h)]^4$
- \begin{align} \mathcal{C}_K(v_h&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\ &\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_{p \text{ is vertex}} \partial_{xy} v_h(p) z_h^\text{xy}(p), \\ \mathcal{D}_K((y_h^\text{value}, y_h^\text{x}, y_h^\text{y}, y_h^\text{xy})&, (z_h^\text{value}, z_h^\text{x}, z_h^\text{y}, z_h^\text{xy})) := \\ &\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_{p \text{ is vertex}} y_h^\text{xy}(p) z_h^\text{xy}(p) \end{align}