Loading...
Searching...
No Matches
strong_algebraic_dirichlet_enforcement.hpp
Go to the documentation of this file.
1
2#pragma once
3
7
8namespace terra::fe {
9
10/// @brief Helper function to modify the right-hand side vector accordingly for strong Dirichlet boundary condition
11/// enforcement.
12///
13/// \note The framework documentation features [a detailed description](#boundary-conditions)
14/// of the strong imposition of Dirichlet boundary conditions.
15///
16/// @param A_neumann the "Neumann" operator (without any modification at the boundary)
17/// @param A_neumann_diag the diagonal of the "Neumann" operator
18/// @param g a coefficient vector with interpolated Dirichlet boundary conditions at the respective boundary nodes, zero
19/// elsewhere
20/// @param tmp a temporary vector
21/// @param b [in/out] RHS coefficient vector before boundary elimination (but including forcing etc.) - will be modified
22/// in this function to impose the Dirichlet BCs (after the function returns, this is what is called \f$b_\mathrm{elim}\f$
23/// in the documentation)
24/// @param mask_data the boundary mask data
25/// @param dirichlet_boundary_mask the flag that indicates where to apply the conditions
26template < typename ScalarType, linalg::OperatorLike OperatorType, typename FlagType >
28 OperatorType& A_neumann,
29 OperatorType& A_neumann_diag,
34 const FlagType& dirichlet_boundary_mask )
35{
36 // g_A <- A * g
37 linalg::apply( A_neumann, g, tmp );
38
39 // b_elim <- b - g_A
40 linalg::lincomb( b, { 1.0, -1.0 }, { b, tmp } );
41
42 // g_D <- diag(A) * g
43 linalg::apply( A_neumann_diag, g, tmp );
44
45 // b_elim <- g_D on the Dirichlet boundary
46 kernels::common::assign_masked_else_keep_old( b.grid_data(), tmp.grid_data(), mask_data, dirichlet_boundary_mask );
47}
48
49template < typename ScalarType, linalg::OperatorLike OperatorType, typename FlagType >
51 OperatorType& A_neumann,
52 OperatorType& A_neumann_diag,
57 const FlagType& dirichlet_boundary_mask )
58{
59 // g_A <- A * g
60 linalg::apply( A_neumann, g, tmp );
61
62 // b_elim <- b - g_A
63 linalg::lincomb( b, { 1.0, -1.0 }, { b, tmp } );
64
65 // g_D <- diag(A) * g
66 linalg::apply( A_neumann_diag, g, tmp );
67
68 // b_elim <- g_D on the Dirichlet boundary
69 kernels::common::assign_masked_else_keep_old( b.grid_data(), tmp.grid_data(), mask_data, dirichlet_boundary_mask );
70}
71
72/// @brief Same as strong_algebraic_dirichlet_enforcement_poisson_like() for homogenous boundary conditions (\f$ g = 0 \f$).
73///
74/// Does not require most of the steps since \f$ g = g_A = g_D = 0 \f$.
75/// Still requires solving \f$ A_\mathrm{elim} x = b_\mathrm{elim} \f$after this.
76template < typename ScalarType, util::FlagLike FlagType >
80 const FlagType& dirichlet_boundary_mask )
81{
82 // b_elim <- 0 on the Dirichlet boundary
83 kernels::common::assign_masked_else_keep_old( b.grid_data(), 0.0, mask_data, dirichlet_boundary_mask );
84}
85
86/// @brief Same as strong_algebraic_dirichlet_enforcement_poisson_like() for Stokes-like systems (with strong
87/// enforcement of velocity boundary conditions).
88template < typename ScalarType, linalg::OperatorLike OperatorType, util::FlagLike FlagType >
90 OperatorType& K_neumann,
91 OperatorType& K_neumann_diag,
96 const FlagType& dirichlet_boundary_mask )
97{
98 // g_A <- A * g
99 linalg::apply( K_neumann, g, tmp );
100
101 // b_elim <- b - g_A
102 linalg::lincomb( b, { 1.0, -1.0 }, { b, tmp } );
103
104 // g_D <- diag(A) * g
105 linalg::apply( K_neumann_diag, g, tmp );
106
107 // b_elim <- g_D on the Dirichlet boundary
109 b.block_1().grid_data(), tmp.block_1().grid_data(), mask_data, dirichlet_boundary_mask );
110}
111
112/// @brief Same as strong_algebraic_homogeneous_dirichlet_enforcement_poisson_like() for Stokes-like systems
113/// (with strong enforcement of zero velocity boundary conditions).
114template < typename ScalarType, util::FlagLike FlagType >
117 const grid::Grid4DDataScalar< FlagType >& mask_data,
118 const FlagType& dirichlet_boundary_mask )
119{
120 // b_elim <- g_D on the Dirichlet boundary
122 b.block_1().grid_data(), ScalarType( 0 ), mask_data, dirichlet_boundary_mask );
123}
124
125} // namespace terra::fe
Block vector consisting of a Q1 vector and a Q1 scalar vector on distributed shell grids.
Definition vector_q1isoq2_q1.hpp:20
const Block1Type & block_1() const
Get const reference to block 1 (vector field).
Definition vector_q1isoq2_q1.hpp:138
const grid::Grid4DDataScalar< ScalarType > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:137
Static assertion: VectorQ1Scalar satisfies VectorLike concept.
Definition vector_q1.hpp:162
const grid::Grid4DDataVec< ScalarType, VecDim > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:280
Definition strong_algebraic_dirichlet_enforcement.hpp:8
void strong_algebraic_velocity_dirichlet_enforcement_stokes_like(OperatorType &K_neumann, OperatorType &K_neumann_diag, const linalg::VectorQ1IsoQ2Q1< ScalarType > &g, linalg::VectorQ1IsoQ2Q1< ScalarType > &tmp, linalg::VectorQ1IsoQ2Q1< ScalarType > &b, const grid::Grid4DDataScalar< FlagType > &mask_data, const FlagType &dirichlet_boundary_mask)
Same as strong_algebraic_dirichlet_enforcement_poisson_like() for Stokes-like systems (with strong en...
Definition strong_algebraic_dirichlet_enforcement.hpp:89
void strong_algebraic_homogeneous_dirichlet_enforcement_poisson_like(linalg::VectorQ1Scalar< ScalarType > &b, const grid::Grid4DDataScalar< FlagType > &mask_data, const FlagType &dirichlet_boundary_mask)
Same as strong_algebraic_dirichlet_enforcement_poisson_like() for homogenous boundary conditions ( ).
Definition strong_algebraic_dirichlet_enforcement.hpp:77
void strong_algebraic_dirichlet_enforcement_poisson_like(OperatorType &A_neumann, OperatorType &A_neumann_diag, const linalg::VectorQ1Scalar< ScalarType > &g, linalg::VectorQ1Scalar< ScalarType > &tmp, linalg::VectorQ1Scalar< ScalarType > &b, const grid::Grid4DDataScalar< FlagType > &mask_data, const FlagType &dirichlet_boundary_mask)
Helper function to modify the right-hand side vector accordingly for strong Dirichlet boundary condit...
Definition strong_algebraic_dirichlet_enforcement.hpp:27
void strong_algebraic_homogeneous_velocity_dirichlet_enforcement_stokes_like(linalg::VectorQ1IsoQ2Q1< ScalarType > &b, const grid::Grid4DDataScalar< FlagType > &mask_data, const FlagType &dirichlet_boundary_mask)
Same as strong_algebraic_homogeneous_dirichlet_enforcement_poisson_like() for Stokes-like systems (wi...
Definition strong_algebraic_dirichlet_enforcement.hpp:115
void strong_algebraic_dirichlet_enforcement_vectorlaplace_like(OperatorType &A_neumann, OperatorType &A_neumann_diag, const linalg::VectorQ1Vec< ScalarType > &g, linalg::VectorQ1Vec< ScalarType > &tmp, linalg::VectorQ1Vec< ScalarType > &b, const grid::Grid4DDataScalar< FlagType > &mask_data, const FlagType &dirichlet_boundary_mask)
Definition strong_algebraic_dirichlet_enforcement.hpp:50
Kokkos::View< ScalarType ****, Layout > Grid4DDataScalar
Definition grid_types.hpp:25
void assign_masked_else_keep_old(const grid::Grid4DDataScalar< ScalarType > &dst, const ScalarType &value, const grid::Grid4DDataScalar< FlagType > &mask_grid, const FlagType mask_value)
Definition grid_operations.hpp:80
void lincomb(Vector &y, const std::vector< ScalarOf< Vector > > &c, const std::vector< Vector > &x, const ScalarOf< Vector > &c0)
Compute a linear combination of vectors. Implements: .
Definition vector.hpp:72
void apply(LinearForm &L, typename LinearForm::DstVectorType &dst)
Apply a linear form and write to a destination vector.
Definition linear_form.hpp:37