libMesh
Loading...
Searching...
No Matches
assembly.C
Go to the documentation of this file.
1// local includes
2#include "assembly.h"
3#include "rb_classes.h"
4
5// libMesh includes
6#include "libmesh/sparse_matrix.h"
7#include "libmesh/numeric_vector.h"
8#include "libmesh/dense_matrix.h"
9#include "libmesh/dense_submatrix.h"
10#include "libmesh/dense_vector.h"
11#include "libmesh/dense_subvector.h"
12#include "libmesh/fe.h"
13#include "libmesh/fe_interface.h"
14#include "libmesh/fe_base.h"
15#include "libmesh/elem_assembly.h"
16#include "libmesh/quadrature_gauss.h"
17#include "libmesh/boundary_info.h"
18#include "libmesh/node.h"
19
20// C++ includes
21#include <functional>
22
23#ifdef LIBMESH_ENABLE_DIRICHLET
24
25// Bring in bits from the libMesh namespace.
26// Just the bits we're using, since this is a header.
30using libMesh::Number;
31using libMesh::Point;
33using libMesh::Real;
35
36// Kronecker delta function
37inline Real kronecker_delta(unsigned int i,
38 unsigned int j)
39{
40 return i == j ? 1. : 0.;
41}
42
43Real elasticity_tensor(unsigned int i,
44 unsigned int j,
45 unsigned int k,
46 unsigned int l)
47{
48 // Define the Poisson ratio and Young's modulus
49 const Real nu = 0.3;
50 const Real E = 1.;
51
52 // Define the Lame constants (lambda_1 and lambda_2) based on nu and E
53 const Real lambda_1 = E * nu / ((1. + nu) * (1. - 2.*nu));
54 const Real lambda_2 = 0.5 * E / (1. + nu);
55
56 return lambda_1 * kronecker_delta(i, j) * kronecker_delta(k, l)
57 + lambda_2 * (kronecker_delta(i, k) * kronecker_delta(j, l) + kronecker_delta(i, l) * kronecker_delta(j, k));
58}
59
61{
62 const unsigned int n_components = rb_sys.n_vars();
63
64 libmesh_assert_less_equal(n_components, 3);
65
66 const unsigned int u_var = rb_sys.u_var;
67 const unsigned int v_var = rb_sys.v_var;
68 const unsigned int w_var = rb_sys.w_var;
69
70 FEBase * elem_fe = nullptr;
71 c.get_element_fe(u_var, elem_fe);
72
73 const std::vector<Real> & JxW = elem_fe->get_JxW();
74
75 // The velocity shape function gradients at interior
76 // quadrature points.
77 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
78
79 // Now we will build the affine operator
80 unsigned int n_qpoints = c.get_element_qrule().n_points();
81
82 std::vector<unsigned int> n_var_dofs(n_components);
83 n_var_dofs[u_var] = c.get_dof_indices(u_var).size();
84 if (n_components > 1)
85 n_var_dofs[v_var] = c.get_dof_indices(v_var).size();
86 if (n_components > 2)
87 n_var_dofs[w_var] = c.get_dof_indices(w_var).size();
88
89 for (unsigned int C_i = 0; C_i < n_components; C_i++)
90 {
91 unsigned int C_j = 0;
92 for (unsigned int C_k = 0; C_k < n_components; C_k++)
93 for (unsigned int C_l = 1; C_l < n_components; C_l++)
94 {
95 Real C_ijkl = elasticity_tensor(C_i, C_j, C_k, C_l);
96 for (unsigned int qp=0; qp<n_qpoints; qp++)
97 for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
98 for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
99 (c.get_elem_jacobian(C_i,C_k))(i,j) +=
100 JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
101 }
102 }
103
104 for (unsigned int C_i = 0; C_i < n_components; C_i++)
105 for (unsigned int C_j = 1; C_j < n_components; C_j++)
106 for (unsigned int C_k = 0; C_k < n_components; C_k++)
107 {
108 unsigned int C_l = 0;
109
110 Real C_ijkl = elasticity_tensor(C_i, C_j, C_k, C_l);
111 for (unsigned int qp=0; qp<n_qpoints; qp++)
112 for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
113 for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
114 (c.get_elem_jacobian(C_i,C_k))(i,j) +=
115 JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
116 }
117
118}
119
121{
122 const unsigned int n_components = rb_sys.n_vars();
123
124 libmesh_assert_less_equal(n_components, 3);
125
126 const unsigned int u_var = rb_sys.u_var;
127 const unsigned int v_var = rb_sys.v_var;
128 const unsigned int w_var = rb_sys.w_var;
129
130 FEBase * elem_fe = nullptr;
131 c.get_element_fe(u_var, elem_fe);
132
133 const std::vector<Real> & JxW = elem_fe->get_JxW();
134
135 // The velocity shape function gradients at interior
136 // quadrature points.
137 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
138
139 // Now we will build the affine operator
140 unsigned int n_qpoints = c.get_element_qrule().n_points();
141
142 std::vector<unsigned int> n_var_dofs(n_components);
143 n_var_dofs[u_var] = c.get_dof_indices(u_var).size();
144 if (n_components > 1)
145 n_var_dofs[v_var] = c.get_dof_indices(v_var).size();
146 if (n_components > 2)
147 n_var_dofs[w_var] = c.get_dof_indices(w_var).size();
148
149 for (unsigned int C_i = 0; C_i < n_components; C_i++)
150 for (unsigned int C_j = 1; C_j < n_components; C_j++)
151 for (unsigned int C_k = 0; C_k < n_components; C_k++)
152 for (unsigned int C_l = 1; C_l < n_components; C_l++)
153 {
154 Real C_ijkl = elasticity_tensor(C_i,C_j,C_k,C_l);
155 for (unsigned int qp=0; qp<n_qpoints; qp++)
156 for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
157 for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
158 (c.get_elem_jacobian(C_i,C_k))(i,j) +=
159 JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
160 }
161}
162
164{
165 const unsigned int n_components = rb_sys.n_vars();
166
167 libmesh_assert_less_equal(n_components, 3);
168
169 const unsigned int u_var = rb_sys.u_var;
170 const unsigned int v_var = rb_sys.v_var;
171 const unsigned int w_var = rb_sys.w_var;
172
173 FEBase * elem_fe = nullptr;
174 c.get_element_fe(u_var, elem_fe);
175
176 const std::vector<Real> & JxW = elem_fe->get_JxW();
177
178 // The velocity shape function gradients at interior
179 // quadrature points.
180 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
181
182 // Now we will build the affine operator
183 unsigned int n_qpoints = c.get_element_qrule().n_points();
184
185 std::vector<unsigned int> n_var_dofs(n_components);
186 n_var_dofs[u_var] = c.get_dof_indices(u_var).size();
187 if (n_components > 1)
188 n_var_dofs[v_var] = c.get_dof_indices(v_var).size();
189 if (n_components > 2)
190 n_var_dofs[w_var] = c.get_dof_indices(w_var).size();
191
192 for (unsigned int C_i = 0; C_i < n_components; C_i++)
193 {
194 unsigned int C_j = 0;
195
196 for (unsigned int C_k = 0; C_k < n_components; C_k++)
197 {
198 unsigned int C_l = 0;
199
200 Real C_ijkl = elasticity_tensor(C_i,C_j,C_k,C_l);
201 for (unsigned int qp=0; qp<n_qpoints; qp++)
202 for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
203 for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
204 (c.get_elem_jacobian(C_i,C_k))(i,j) +=
205 JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
206 }
207 }
208}
209
211{
213 (&c.get_elem(), c.side, BOUNDARY_ID_MAX_X))
214 {
215 const unsigned int u_var = 0;
216
217 FEBase * side_fe = nullptr;
218 c.get_side_fe(u_var, side_fe);
219
220 const std::vector<Real> & JxW_side = side_fe->get_JxW();
221
222 const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
223
224 // The number of local degrees of freedom in each variable
225 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
226
227 // Now we will build the affine operator
228 unsigned int n_qpoints = c.get_side_qrule().n_points();
229 DenseSubVector<Number> & Fu = c.get_elem_residual(u_var);
230
231 for (unsigned int qp=0; qp < n_qpoints; qp++)
232 for (unsigned int i=0; i < n_u_dofs; i++)
233 Fu(i) += JxW_side[qp] * (1. * phi_side[i][qp]);
234 }
235}
236
238{
240 (&c.get_elem(), c.side, BOUNDARY_ID_MAX_X))
241 {
242 const unsigned int u_var = 0;
243 const unsigned int v_var = 1;
244
245 FEBase * side_fe = nullptr;
246 c.get_side_fe(u_var, side_fe);
247
248 const std::vector<Real> & JxW_side = side_fe->get_JxW();
249
250 const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
251
252 // The number of local degrees of freedom in each variable
253 const unsigned int n_v_dofs = c.get_dof_indices(u_var).size();
254
255 // Now we will build the affine operator
256 unsigned int n_qpoints = c.get_side_qrule().n_points();
257 DenseSubVector<Number> & Fv = c.get_elem_residual(v_var);
258
259 for (unsigned int qp=0; qp < n_qpoints; qp++)
260 for (unsigned int i=0; i < n_v_dofs; i++)
261 Fv(i) += JxW_side[qp] * (1. * phi_side[i][qp]);
262 }
263}
264
266{
268 (&c.get_elem(), c.side, BOUNDARY_ID_MAX_X))
269 {
270 const unsigned int u_var = 0;
271 const unsigned int w_var = 2;
272
273 FEBase * side_fe = nullptr;
274 c.get_side_fe(u_var, side_fe);
275
276 const std::vector<Real> & JxW_side = side_fe->get_JxW();
277
278 const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
279
280 // The number of local degrees of freedom in each variable
281 const unsigned int n_w_dofs = c.get_dof_indices(w_var).size();
282
283 // Now we will build the affine operator
284 unsigned int n_qpoints = c.get_side_qrule().n_points();
285 DenseSubVector<Number> & Fw = c.get_elem_residual(w_var);
286
287 for (unsigned int qp=0; qp < n_qpoints; qp++)
288 for (unsigned int i=0; i < n_w_dofs; i++)
289 Fw(i) += JxW_side[qp] * (1. * phi_side[i][qp]);
290 }
291}
292
293void AssemblyPointLoadX::get_nodal_rhs_values(std::map<numeric_index_type, Number> & values,
294 const System & sys,
295 const Node & node)
296{
297 // First clear the values map
298 values.clear();
299
301 (&node, NODE_BOUNDARY_ID))
302 {
303 numeric_index_type dof_index =
304 node.dof_number(sys.number(), sys.variable_number("u"), 0);
305 values[dof_index] = 1.;
306 }
307}
308
309void AssemblyPointLoadY::get_nodal_rhs_values(std::map<numeric_index_type, Number> & values,
310 const System & sys,
311 const Node & node)
312{
313 // First clear the values map
314 values.clear();
315
317 (&node, NODE_BOUNDARY_ID))
318 {
319 numeric_index_type dof_index =
320 node.dof_number(sys.number(), sys.variable_number("v"), 0);
321 values[dof_index] = 1.;
322 }
323}
324
325void AssemblyPointLoadZ::get_nodal_rhs_values(std::map<numeric_index_type, Number> & values,
326 const System & sys,
327 const Node & node)
328{
329 // First clear the values map
330 values.clear();
331
333 (&node, NODE_BOUNDARY_ID))
334 {
335 numeric_index_type dof_index =
336 node.dof_number(sys.number(), sys.variable_number("w"), 0);
337 values[dof_index] = 1.;
338 }
339}
340
342{
343 const unsigned int n_components = rb_sys.n_vars();
344
345 libmesh_assert_less_equal(n_components, 3);
346
347 const unsigned int u_var = rb_sys.u_var;
348 const unsigned int v_var = rb_sys.v_var;
349 const unsigned int w_var = rb_sys.w_var;
350
351 FEBase * elem_fe = nullptr;
352 c.get_element_fe(u_var, elem_fe);
353
354 const std::vector<Real> & JxW = elem_fe->get_JxW();
355
356 // The velocity shape function gradients at interior
357 // quadrature points.
358 const std::vector<std::vector<RealGradient>>& dphi = elem_fe->get_dphi();
359
360 // (u_var, v_var, w_var) all have the same number of dofs
361 const unsigned int n_dofs = c.get_dof_indices(u_var).size();
362
363 // Now we will build the affine operator
364 unsigned int n_qpoints = c.get_element_qrule().n_points();
365
366 // Get references to stiffness matrix diagonal blocks
367 std::reference_wrapper<DenseSubMatrix<Number>> Kdiag[3] =
368 {
369 c.get_elem_jacobian(u_var, u_var),
370 c.get_elem_jacobian(v_var, v_var),
371 c.get_elem_jacobian(w_var, w_var)
372 };
373
374 for (unsigned int qp=0; qp<n_qpoints; qp++)
375 for (unsigned int d=0; d<n_components; ++d)
376 for (unsigned int i=0; i<n_dofs; i++)
377 for (unsigned int j=0; j<n_dofs; j++)
378 Kdiag[d](i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
379}
380
381#endif // LIBMESH_ENABLE_DIRICHLET
unsigned int u_var
Variable numbers and approximation order.
Definition rb_classes.h:136
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
ElemAssembly provides a per-element (interior and boundary) assembly functionality.
This class provides an encapsulated access to all static public member functions of finite element cl...
This class provides all data required for a physics package (e.g.
Definition fem_context.h:63
void get_side_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for edge/face (2D/3D) finite element object for variable var for the largest dimension in th...
unsigned char side
Current side for side_* to examine.
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
const Elem & get_elem() const
Accessor for current Elem object.
void get_element_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for interior finite element object for variable var for the largest dimension in the mesh.
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
A Node is like a Point, but with more information.
Definition node.h:55
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
unsigned int n_points() const
Definition quadrature.h:131
This class is part of the rbOOmit framework.
Definition rb_theta.h:47
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
unsigned int variable_number(std::string_view var) const
Definition system.C:1398
unsigned int n_vars() const
Definition system.C:2674
unsigned int number() const
Definition system.h:2393
const MeshBase & get_mesh() const
Definition system.h:2401
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real kronecker_delta(unsigned int i, unsigned int j)
Definition assembly.C:37
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
Definition assembly.C:43
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.C:60
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.C:120
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.C:163
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition assembly.C:210
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition assembly.C:237
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition assembly.C:265
virtual void get_nodal_rhs_values(std::map< numeric_index_type, Number > &values, const System &sys, const Node &node)
Definition assembly.C:293
virtual void get_nodal_rhs_values(std::map< numeric_index_type, Number > &values, const System &sys, const Node &node)
Definition assembly.C:309
virtual void get_nodal_rhs_values(std::map< numeric_index_type, Number > &values, const System &sys, const Node &node)
Definition assembly.C:325
ElasticityRBConstruction & rb_sys
The ElasticityRBConstruction object that will use this assembly.
Definition assembly.h:56
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.C:341