libMesh
Loading...
Searching...
No Matches
assembly.h
Go to the documentation of this file.
1#ifndef ASSEMBLY_H
2#define ASSEMBLY_H
3
4#if defined(LIBMESH_HAVE_SLEPC) && defined(LIBMESH_HAVE_GLPK)
5
6#include "libmesh/sparse_matrix.h"
7#include "libmesh/numeric_vector.h"
8#include "libmesh/dense_matrix.h"
9#include "libmesh/dense_vector.h"
10#include "libmesh/fe.h"
11#include "libmesh/fe_interface.h"
12#include "libmesh/fe_base.h"
13#include "libmesh/elem_assembly.h"
14#include "libmesh/quadrature_gauss.h"
15
16// rbOOmit includes
17#include "libmesh/rb_theta.h"
18#include "libmesh/rb_assembly_expansion.h"
19
20// Bring in bits from the libMesh namespace.
21// Just the bits we're using, since this is a header.
25using libMesh::Number;
26using libMesh::Point;
28using libMesh::Real;
30using libMesh::FEBase;
31
32// Functors for the parameter-dependent part of the affine decomposition of the PDE
33// The RHS and outputs just require a constant value of 1, so use a default RBTheta object there
34struct ThetaA0 : RBTheta { virtual Number evaluate(const RBParameters & mu) { return mu.get_value("mu_0"); } };
35struct ThetaA1 : RBTheta { virtual Number evaluate(const RBParameters & mu) { return mu.get_value("mu_1"); } };
36struct ThetaA2 : RBTheta { virtual Number evaluate(const RBParameters & mu) { return mu.get_value("mu_2"); } };
37
39{
40 // Assemble the H1 inner product. This will be used as the inner product
41 // for this problem.
42 virtual void interior_assembly(FEMContext & c)
43 {
44 const unsigned int u_var = 0;
45
46 FEBase * elem_fe = nullptr;
47 c.get_element_fe(u_var, elem_fe);
48
49 const std::vector<Real> & JxW = elem_fe->get_JxW();
50
51 const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
52
53 // The velocity shape function gradients at interior
54 // quadrature points.
55 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
56
57 // The number of local degrees of freedom in each variable
58 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
59
60 // Now we will build the affine operator
61 unsigned int n_qpoints = c.get_element_qrule().n_points();
62
63 for (unsigned int qp=0; qp != n_qpoints; qp++)
64 for (unsigned int i=0; i != n_u_dofs; i++)
65 for (unsigned int j=0; j != n_u_dofs; j++)
66 c.get_elem_jacobian()(i,j) += JxW[qp] * (phi[j][qp]*phi[i][qp] + dphi[j][qp]*dphi[i][qp]);
67 }
68};
69
70
71struct A0 : ElemAssembly
72{
73 // Assemble the Laplacian operator
74 virtual void interior_assembly(FEMContext & c)
75 {
76 const unsigned int u_var = 0;
77
78 FEBase * elem_fe = nullptr;
79 c.get_element_fe(u_var, elem_fe);
80
81 const std::vector<Real> & JxW = elem_fe->get_JxW();
82
83 // The velocity shape function gradients at interior
84 // quadrature points.
85 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
86
87 // The number of local degrees of freedom in each variable
88 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
89
90 // Now we will build the affine operator
91 unsigned int n_qpoints = c.get_element_qrule().n_points();
92
93 Real
94 min_x=0.,
95 max_x=0.5;
96
97 Point avg = c.get_elem().vertex_average();
98 if ((min_x <= avg(0)) && (avg(0) < max_x))
99 for (unsigned int qp=0; qp != n_qpoints; qp++)
100 for (unsigned int i=0; i != n_u_dofs; i++)
101 for (unsigned int j=0; j != n_u_dofs; j++)
102 c.get_elem_jacobian()(i,j) += JxW[qp] * dphi[j][qp]*dphi[i][qp];
103 }
104};
105
106struct A1 : ElemAssembly
107{
108 // Assemble the Laplacian operator
110 {
111 const unsigned int u_var = 0;
112
113 FEBase * elem_fe = nullptr;
114 c.get_element_fe(u_var, elem_fe);
115
116 const std::vector<Real> & JxW = elem_fe->get_JxW();
117
118 // The velocity shape function gradients at interior
119 // quadrature points.
120 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
121
122 // The number of local degrees of freedom in each variable
123 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
124
125 // Now we will build the affine operator
126 unsigned int n_qpoints = c.get_element_qrule().n_points();
127
128 Real
129 min_x=0.5,
130 max_x=1.;
131
132 Point avg = c.get_elem().vertex_average();
133 if ((min_x <= avg(0)) && (avg(0) <= max_x))
134 for (unsigned int qp=0; qp != n_qpoints; qp++)
135 for (unsigned int i=0; i != n_u_dofs; i++)
136 for (unsigned int j=0; j != n_u_dofs; j++)
137 c.get_elem_jacobian()(i,j) += JxW[qp] * dphi[j][qp]*dphi[i][qp];
138 }
139};
140
141struct A2 : ElemAssembly
142{
143 // Convection in the x-direction
145 {
146 const unsigned int u_var = 0;
147
148 FEBase * elem_fe = nullptr;
149 c.get_element_fe(u_var, elem_fe);
150
151 const std::vector<Real> & JxW = elem_fe->get_JxW();
152
153 const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
154
155 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
156
157 // The number of local degrees of freedom in each variable
158 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
159
160 // Now we will build the affine operator
161 unsigned int n_qpoints = c.get_element_qrule().n_points();
162
163 for (unsigned int qp=0; qp != n_qpoints; qp++)
164 for (unsigned int i=0; i != n_u_dofs; i++)
165 for (unsigned int j=0; j != n_u_dofs; j++)
166 c.get_elem_jacobian()(i,j) -= JxW[qp] * dphi[i][qp](0)*phi[j][qp];
167 }
168};
169
170
171struct F0 : ElemAssembly
172{
173 // Source term, 1 throughout the domain
175 {
176 const unsigned int u_var = 0;
177
178 FEBase * elem_fe = nullptr;
179 c.get_element_fe(u_var, elem_fe);
180
181 const std::vector<Real> & JxW = elem_fe->get_JxW();
182
183 const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
184
185 // The number of local degrees of freedom in each variable
186 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
187
188 // Now we will build the affine operator
189 unsigned int n_qpoints = c.get_element_qrule().n_points();
190
191 for (unsigned int qp=0; qp != n_qpoints; qp++)
192 for (unsigned int i=0; i != n_u_dofs; i++)
193 c.get_elem_residual()(i) += JxW[qp] * (1.*phi[i][qp]);
194 }
195};
196
198{
199 OutputAssembly(Real min_x_in, Real max_x_in,
200 Real min_y_in, Real max_y_in) :
201 min_x(min_x_in),
202 max_x(max_x_in),
203 min_y(min_y_in),
204 max_y(max_y_in)
205 {}
206
207 // Output: Average value over the region [min_x,max_x]x[min_y,max_y]
209 {
210 const unsigned int u_var = 0;
211
212 FEBase * elem_fe = nullptr;
213 c.get_element_fe(u_var, elem_fe);
214
215 const std::vector<Real> & JxW = elem_fe->get_JxW();
216
217 const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
218
219 // The number of local degrees of freedom in each variable
220 const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
221
222 // Now we will build the affine operator
223 unsigned int n_qpoints = c.get_element_qrule().n_points();
224
225 Real output_area = (max_x-min_x) * (max_y-min_y);
226
227 Point avg = c.get_elem().vertex_average();
228 if ((min_x <= avg(0)) && (avg(0) <= max_x) &&
229 (min_y <= avg(1)) && (avg(1) <= max_y))
230 for (unsigned int qp=0; qp != n_qpoints; qp++)
231 for (unsigned int i=0; i != n_u_dofs; i++)
232 c.get_elem_residual()(i) += JxW[qp] * (1.*phi[i][qp]) / output_area;
233 }
234
235 // Member variables that define the output region in 2D
236 Real min_x, max_x, min_y, max_y;
237};
238
239// Define an RBThetaExpansion class for this PDE
240struct Ex02RBThetaExpansion : RBThetaExpansion
241{
242
247 {
248 // set up the RBThetaExpansion object
249 attach_A_theta(&theta_a_0); // Attach the lhs theta
250 attach_A_theta(&theta_a_1);
251 attach_A_theta(&theta_a_2);
252
253 attach_F_theta(&rb_theta); // Attach the rhs theta
254
255 attach_output_theta(&rb_theta); // Attach output 0 theta
256 attach_output_theta(&rb_theta); // Attach output 1 theta
257 attach_output_theta(&rb_theta); // Attach output 2 theta
258 attach_output_theta(&rb_theta); // Attach output 3 theta
259 }
260
261 // The RBTheta member variables
265 RBTheta rb_theta; // Default RBTheta object, just returns 1.
266};
267
268// Define an RBAssemblyExpansion class for this PDE
269struct Ex02RBAssemblyExpansion : RBAssemblyExpansion
270{
271
276 :
277 L0(0.72, 0.88, 0.72, 0.88), // We make sure these output regions conform to the mesh
278 L1(0.12, 0.28, 0.72, 0.88),
279 L2(0.12, 0.28, 0.12, 0.28),
280 L3(0.72, 0.88, 0.12, 0.28)
281 {
282 // And set up the RBAssemblyExpansion object
283 attach_A_assembly(&A0_assembly); // Attach the lhs assembly
284 attach_A_assembly(&A1_assembly);
285 attach_A_assembly(&A2_assembly);
286
287 attach_F_assembly(&F0_assembly); // Attach the rhs assembly
288
289 attach_output_assembly(&L0); // Attach output 0 assembly
290 attach_output_assembly(&L1); // Attach output 1 assembly
291 attach_output_assembly(&L2); // Attach output 2 assembly
292 attach_output_assembly(&L3); // Attach output 3 assembly
293 }
294
295 // The ElemAssembly objects
305};
306
307#endif // LIBMESH_HAVE_SLEPC && LIBMESH_HAVE_GLPK
308
309#endif
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.
ElemAssembly provides a per-element (interior and boundary) assembly functionality.
Point vertex_average() const
Definition elem.C:669
This class forms the foundation from which generic finite elements may be derived.
Definition fe_base.h:86
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
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.
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.
Real get_value(const std::string &param_name) const
Get the value of the specified parameter, throw an error if it does not exist.
This class is part of the rbOOmit framework.
Definition rb_theta.h:47
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition assembly.h:40
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:74
Definition assembly.h:70
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:109
Definition assembly.h:99
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:144
Definition assembly.h:39
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:42
OutputAssembly L1
Definition assembly.h:302
OutputAssembly L0
Definition assembly.h:301
OutputAssembly L3
Definition assembly.h:304
Ex02RBAssemblyExpansion()
Constructor.
Definition assembly.h:275
OutputAssembly L2
Definition assembly.h:303
Ex02RBThetaExpansion()
Constructor.
Definition assembly.h:246
Definition assembly.h:128
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:174
Output assembly object which computes the average value of the solution variable inside a user-provid...
Definition assembly.h:154
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition assembly.h:208
OutputAssembly(Real min_x_in, Real max_x_in, Real min_y_in, Real max_y_in)
Definition assembly.h:199
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition assembly.h:34
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition assembly.h:35
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition assembly.h:36