libMesh
assembly.h
Go to the documentation of this file.
1 #ifndef ASSEMBLY_H
2 #define ASSEMBLY_H
3 
4 #include "libmesh/sparse_matrix.h"
5 #include "libmesh/numeric_vector.h"
6 #include "libmesh/dense_matrix.h"
7 #include "libmesh/dense_vector.h"
8 #include "libmesh/fe.h"
9 #include "libmesh/fe_interface.h"
10 #include "libmesh/fe_base.h"
11 #include "libmesh/elem_assembly.h"
12 #include "libmesh/quadrature_gauss.h"
13 #include "libmesh/boundary_info.h"
14 
15 // rbOOmit includes
16 #include "libmesh/rb_theta.h"
17 #include "libmesh/rb_assembly_expansion.h"
18 #include "libmesh/rb_parametrized_function.h"
19 #include "libmesh/rb_eim_construction.h"
20 #include "libmesh/rb_eim_theta.h"
21 
22 // Bring in bits from the libMesh namespace.
23 // Just the bits we're using, since this is a header.
29 using libMesh::Number;
30 using libMesh::Point;
35 using libMesh::RBTheta;
41 using libMesh::Real;
43 using libMesh::Elem;
44 using libMesh::FEBase;
47 
48 // The function we're approximating with EIM
50 {
51  unsigned int get_n_components() const override
52  {
53  return 3;
54  }
55 
56  virtual std::vector<Number>
57  evaluate(const RBParameters & mu,
58  const Point & p,
59  dof_id_type /*elem_id*/,
60  unsigned int /*qp*/,
61  subdomain_id_type /*subdomain_id*/,
62  const std::vector<Point> & /*p_perturb*/,
63  const std::vector<Real> & /*phi_i_qp*/) override
64  {
65  Real curvature = mu.get_value("curvature");
66 
67  return {1. + curvature*p(0), 1. + curvature*p(0), 1./(1. + curvature*p(0))};
68  }
69 };
70 
71 struct ThetaA0 : RBTheta
72 {
73  virtual Number evaluate(const RBParameters & mu)
74  {
75  return mu.get_value("kappa") * mu.get_value("Bi");
76  }
77 };
78 
79 struct AssemblyA0 : ElemAssembly
80 {
81  virtual void boundary_assembly(FEMContext & c)
82  {
83  std::vector<boundary_id_type> bc_ids;
85  for (const auto & bc_id : bc_ids)
86  if (bc_id == 1 || bc_id == 2 || bc_id == 3 || bc_id == 4)
87  {
88  const unsigned int u_var = 0;
89 
90  FEBase * side_fe = nullptr;
91  c.get_side_fe(u_var, side_fe);
92 
93  const std::vector<Real> & JxW_side = side_fe->get_JxW();
94 
95  const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
96 
97  // The number of local degrees of freedom in each variable
98  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
99 
100  // Now we will build the affine operator
101  unsigned int n_sidepoints = c.get_side_qrule().n_points();
102 
103  for (unsigned int qp=0; qp != n_sidepoints; qp++)
104  for (unsigned int i=0; i != n_u_dofs; i++)
105  for (unsigned int j=0; j != n_u_dofs; j++)
106  c.get_elem_jacobian()(i,j) += JxW_side[qp] * phi_side[j][qp]*phi_side[i][qp];
107 
108  break;
109  }
110  }
111 };
112 
113 struct ThetaA1 : RBTheta
114 {
115  virtual Number evaluate(const RBParameters & mu)
116  {
117  return mu.get_value("kappa") * mu.get_value("Bi") * mu.get_value("curvature");
118  }
119 };
120 
121 struct AssemblyA1 : ElemAssembly
122 {
123  virtual void boundary_assembly(FEMContext & c)
124  {
125  std::vector<boundary_id_type> bc_ids;
127  for (const auto & bc_id : bc_ids)
128  if (bc_id == 1 || bc_id == 3) // y == -0.2, y == 0.2
129  {
130  const unsigned int u_var = 0;
131 
132  FEBase * side_fe = nullptr;
133  c.get_side_fe(u_var, side_fe);
134 
135  const std::vector<Real> & JxW_side = side_fe->get_JxW();
136 
137  const std::vector<std::vector<Real>> & phi_side = side_fe->get_phi();
138 
139  const std::vector<Point> & xyz = side_fe->get_xyz();
140 
141  // The number of local degrees of freedom in each variable
142  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
143 
144  // Now we will build the affine operator
145  unsigned int n_sidepoints = c.get_side_qrule().n_points();
146 
147  for (unsigned int qp=0; qp != n_sidepoints; qp++)
148  {
149  Real x_hat = xyz[qp](0);
150 
151  for (unsigned int i=0; i != n_u_dofs; i++)
152  for (unsigned int j=0; j != n_u_dofs; j++)
153  c.get_elem_jacobian()(i,j) += JxW_side[qp] * x_hat * phi_side[j][qp]*phi_side[i][qp];
154  }
155 
156  break;
157  }
158  }
159 };
160 
161 struct ThetaA2 : RBTheta {
162  virtual Number evaluate(const RBParameters & mu)
163  {
164  return 0.2*mu.get_value("kappa") * mu.get_value("Bi") * mu.get_value("curvature");
165  }
166 };
167 struct AssemblyA2 : ElemAssembly
168 {
169  virtual void boundary_assembly(FEMContext & c)
170  {
171  std::vector<boundary_id_type> bc_ids;
173  for (const auto & bc_id : bc_ids)
174  if (bc_id == 2 || bc_id == 4) // x == 0.2, x == -0.2
175  {
176  const unsigned int u_var = 0;
177 
178  FEBase * side_fe = nullptr;
179  c.get_side_fe(u_var, side_fe);
180 
181  const std::vector<Real> & JxW_side = side_fe->get_JxW();
182 
183  const std::vector<std::vector<Real>> & phi_side = side_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_sidepoints = c.get_side_qrule().n_points();
190 
191  if (bc_id == 2)
192  {
193  for (unsigned int qp=0; qp != n_sidepoints; qp++)
194  {
195  for (unsigned int i=0; i != n_u_dofs; i++)
196  for (unsigned int j=0; j != n_u_dofs; j++)
197  c.get_elem_jacobian()(i,j) += JxW_side[qp] * phi_side[j][qp]*phi_side[i][qp];
198  }
199  }
200 
201  if (bc_id == 4)
202  {
203  for (unsigned int qp=0; qp != n_sidepoints; qp++)
204  {
205  for (unsigned int i=0; i != n_u_dofs; i++)
206  for (unsigned int j=0; j != n_u_dofs; j++)
207  c.get_elem_jacobian()(i,j) -= JxW_side[qp] * phi_side[j][qp]*phi_side[i][qp];
208  }
209  }
210  }
211  }
212 };
213 
215 {
216  ThetaEIM(RBEIMEvaluation & rb_eim_eval_in, unsigned int index_in) :
217  RBEIMTheta(rb_eim_eval_in, index_in)
218  {}
219 
220  virtual Number evaluate(const RBParameters & mu)
221  {
222  return mu.get_value("kappa") * RBEIMTheta::evaluate(mu);
223  }
224 };
225 
227 {
229  unsigned int basis_function_index_in) :
230  RBEIMAssembly(rb_eim_con_in,
231  basis_function_index_in)
232  {}
233 
234  virtual void interior_assembly(FEMContext & c)
235  {
236  // PDE variable numbers
237  const unsigned int u_var = 0;
238 
239  // EIM variable numbers
240  const unsigned int Gx_var = 0;
241  const unsigned int Gy_var = 1;
242  const unsigned int Gz_var = 2;
243 
244  FEBase * elem_fe = nullptr;
245  c.get_element_fe(u_var, elem_fe);
246 
247  const std::vector<Real> & JxW = elem_fe->get_JxW();
248 
249  const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
250 
251  // The number of local degrees of freedom in each variable
252  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
253 
254  std::vector<Number> eim_values_Gx;
256  Gx_var,
257  eim_values_Gx);
258 
259  std::vector<Number> eim_values_Gy;
261  Gy_var,
262  eim_values_Gy);
263 
264  std::vector<Number> eim_values_Gz;
266  Gz_var,
267  eim_values_Gz);
268 
269  for (unsigned int qp=0; qp != c.get_element_qrule().n_points(); qp++)
270  for (unsigned int i=0; i != n_u_dofs; i++)
271  for (unsigned int j=0; j != n_u_dofs; j++)
272  c.get_elem_jacobian()(i,j) += JxW[qp] * (eim_values_Gx[qp]*dphi[i][qp](0)*dphi[j][qp](0) +
273  eim_values_Gy[qp]*dphi[i][qp](1)*dphi[j][qp](1) +
274  eim_values_Gz[qp]*dphi[i][qp](2)*dphi[j][qp](2));
275  }
276 };
277 
278 
279 struct ThetaF0 : RBTheta
280 {
281  virtual Number evaluate(const RBParameters &) { return 1.; }
282 };
283 
284 struct AssemblyF0 : ElemAssembly
285 {
286 
287  virtual void interior_assembly(FEMContext & c)
288  {
289  const unsigned int u_var = 0;
290 
291  FEBase * elem_fe = nullptr;
292  c.get_element_fe(u_var, elem_fe);
293 
294  const std::vector<Real> & JxW = elem_fe->get_JxW();
295 
296  const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
297 
298  // The number of local degrees of freedom in each variable
299  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
300 
301  // Now we will build the affine operator
302  unsigned int n_qpoints = c.get_element_qrule().n_points();
303 
304  for (unsigned int qp=0; qp != n_qpoints; qp++)
305  for (unsigned int i=0; i != n_u_dofs; i++)
306  c.get_elem_residual()(i) += JxW[qp] * (1.*phi[i][qp]);
307  }
308 };
309 
310 struct ThetaF1 : RBTheta
311 {
312  virtual Number evaluate(const RBParameters & mu)
313  {
314  return mu.get_value("curvature");
315  }
316 };
317 
318 struct AssemblyF1 : ElemAssembly
319 {
320 
321  virtual void interior_assembly(FEMContext & c)
322  {
323  const unsigned int u_var = 0;
324 
325  FEBase * elem_fe = nullptr;
326  c.get_element_fe(u_var, elem_fe);
327 
328  const std::vector<Real> & JxW = elem_fe->get_JxW();
329 
330  const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
331 
332  const std::vector<Point> & xyz = elem_fe->get_xyz();
333 
334  // The number of local degrees of freedom in each variable
335  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
336 
337  // Now we will build the affine operator
338  unsigned int n_qpoints = c.get_element_qrule().n_points();
339 
340  for (unsigned int qp=0; qp != n_qpoints; qp++)
341  {
342  Real x_hat = xyz[qp](0);
343 
344  for (unsigned int i=0; i != n_u_dofs; i++)
345  c.get_elem_residual()(i) += JxW[qp] * (1.*x_hat*phi[i][qp]);
346  }
347  }
348 };
349 
351 {
352  // Assemble the Laplacian operator
353  virtual void interior_assembly(FEMContext & c)
354  {
355  const unsigned int u_var = 0;
356 
357  FEBase * elem_fe = nullptr;
358  c.get_element_fe(u_var, elem_fe);
359 
360  const std::vector<Real> & JxW = elem_fe->get_JxW();
361 
362  const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
363 
364  // The number of local degrees of freedom in each variable
365  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
366 
367  // Now we will build the affine operator
368  unsigned int n_qpoints = c.get_element_qrule().n_points();
369 
370  for (unsigned int qp=0; qp != n_qpoints; qp++)
371  for (unsigned int i=0; i != n_u_dofs; i++)
372  for (unsigned int j=0; j != n_u_dofs; j++)
373  c.get_elem_jacobian()(i,j) += JxW[qp] * dphi[j][qp]*dphi[i][qp];
374  }
375 };
376 
377 // Define an RBThetaExpansion class for this PDE
378 // The A terms depend on EIM, so we deal with them later
380 {
381 
386  {
390  attach_F_theta(&theta_f0); // Attach the rhs theta
392  }
393 
394  // The RBTheta member variables
400 };
401 
402 // Define an RBAssemblyExpansion class for this PDE
403 // The A terms depend on EIM, so we deal with them later
405 {
406 
411  {
415  attach_F_assembly(&assembly_f0); // Attach the rhs assembly
417  }
418 
419  // The ElemAssembly objects
425 };
426 
427 #endif
unsigned int get_n_components() const override
Specify the number of components in this parametrized function.
Definition: assembly.h:51
Real get_value(const std::string &param_name) const
Get the value of the specified parameter, throw an error if it does not exist.
Definition: rb_parameters.C:65
RealVectorValue RealGradient
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
ThetaF1 theta_f1
Definition: assembly.h:399
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...
Definition: fem_context.h:317
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition: assembly.h:123
const Elem & get_elem() const
Accessor for current Elem object.
Definition: fem_context.h:908
A simple functor class that provides a RBParameter-dependent function.
This class provides functionality required to define an RBTheta object that arises from an "Empirical...
Definition: rb_eim_theta.h:42
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn&#39;t work with exodusII at all...
Definition: id_types.h:43
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition: assembly.h:115
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition: assembly.h:73
This class is part of the rbOOmit framework.
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
ThetaF0 theta_f0
Definition: assembly.h:398
void evaluate_basis_function(dof_id_type elem_id, unsigned int var, std::vector< Number > &values)
Return the basis function values for all quadrature points for variable var on element elem_id...
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
Ex6ThetaExpansion()
Constructor.
Definition: assembly.h:385
const MeshBase & get_mesh() const
Definition: system.h:2358
void attach_F_assembly(ElemAssembly *Fq_assembly)
Attach ElemAssembly object for the right-hand side (both interior and boundary assembly).
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
AssemblyF1 assembly_f1
Definition: assembly.h:424
virtual void attach_F_theta(RBTheta *theta_q_f)
Attach a pointer to a functor object that defines one of the theta_q_a terms.
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition: assembly.h:169
This class provides functionality required to define an assembly object that arises from an "Empirica...
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition: assembly.h:287
int8_t boundary_id_type
Definition: id_types.h:51
ThetaEIM(RBEIMEvaluation &rb_eim_eval_in, unsigned int index_in)
Definition: assembly.h:216
dof_id_type id() const
Definition: dof_object.h:828
const System & get_system() const
Accessor for associated system.
Definition: diff_context.h:106
Definition: assembly.h:49
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition: assembly.h:234
Defines a dense submatrix for use in Finite Element-type computations.
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition: assembly.h:162
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
Definition: diff_context.h:363
unsigned int n_points() const
Definition: quadrature.h:131
AssemblyF0 assembly_f0
Definition: assembly.h:423
AssemblyA0 assembly_a0
Definition: assembly.h:420
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:52
virtual Number evaluate(const RBParameters &)
Evaluate the functor object for the given parameter.
Definition: assembly.h:281
FEGenericBase< Real > FEBase
This class provides an encapsulated access to all static public member functions of finite element cl...
Definition: fe_interface.h:65
virtual Number evaluate(const RBParameters &mu)
Evaluate this RBEIMTheta object at the parameter mu.
Definition: assembly.h:220
AssemblyA2 assembly_a2
Definition: assembly.h:422
void attach_A_assembly(ElemAssembly *Aq_assembly)
Attach ElemAssembly object for the left-hand side (both interior and boundary assembly).
virtual void boundary_assembly(FEMContext &c)
Perform the element boundary assembly.
Definition: assembly.h:81
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:242
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
ThetaA0 theta_a0
Definition: assembly.h:395
unsigned char side
Current side for side_* to examine.
Definition: fem_context.h:1013
ThetaA1 theta_a1
Definition: assembly.h:396
virtual Number evaluate(const RBParameters &mu)
Evaluate the functor object for the given parameter.
Definition: assembly.h:312
virtual std::vector< Number > evaluate(const RBParameters &mu, const Point &p, dof_id_type, unsigned int, subdomain_id_type, const std::vector< Point > &, const std::vector< Real > &) override
Definition: assembly.h:57
This class stores the set of ElemAssembly functor objects that define the "parameter-independent expa...
ElemAssembly provides a per-element (interior and boundary) assembly functionality.
Definition: elem_assembly.h:38
AssemblyEIM(RBEIMConstruction &rb_eim_con_in, unsigned int basis_function_index_in)
Definition: assembly.h:228
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...
Definition: fem_context.h:277
This class is part of the rbOOmit framework.
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition: assembly.h:321
Ex6AssemblyExpansion()
Constructor.
Definition: assembly.h:410
AssemblyA1 assembly_a1
Definition: assembly.h:421
ThetaA2 theta_a2
Definition: assembly.h:397
This class is part of the rbOOmit framework.
Definition: rb_theta.h:46
This class enables evaluation of an Empirical Interpolation Method (EIM) approximation.
virtual void interior_assembly(FEMContext &c)
Perform the element interior assembly.
Definition: assembly.h:353
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
Definition: fem_context.h:802
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem. ...
Definition: fem_context.h:809
uint8_t dof_id_type
Definition: id_types.h:67
virtual void attach_A_theta(RBTheta *theta_q_a)
Attach a pointer to a functor object that defines one of the theta_q_a terms.