libMesh
H-qoi.C
Go to the documentation of this file.
1 #include "H-qoi.h"
2 
3 #include "libmesh/system.h"
4 
5 // Here we define the functions to compute the QoI (side_qoi)
6 // and supply the right hand side for the associated adjoint problem (side_qoi_derivative)
7 
8 using namespace libMesh;
9 
11 {
12  //Only 1 qoi to worry about
13  sys.init_qois(1);
14 }
15 
17 {
18  FEMContext & c = cast_ref<FEMContext &>(context);
19 
20  u_var = c.get_system().variable_number("u");
21  p_var = c.get_system().variable_number("p");
22 
23  // Note that the concentration and velocity components
24  // use the same basis.
25  FEBase * u_elem_fe = nullptr;
26  c.get_element_fe(u_var, u_elem_fe);
27  u_elem_fe->get_nothing();
28 
29  FEBase * p_elem_fe = nullptr;
30  c.get_element_fe(p_var, p_elem_fe);
31  p_elem_fe->get_nothing();
32 
33  FEBase * side_fe = nullptr;
34  c.get_side_fe(u_var, side_fe);
35 
36  side_fe->get_JxW();
37  side_fe->get_phi();
38  side_fe->get_xyz();
39 
40  // Don't waste time on side computations for p
41  FEBase * p_side_fe = nullptr;
42  c.get_side_fe(p_var, p_side_fe);
43  p_side_fe->get_nothing();
44 }
45 
46 // This function supplies the right hand side for the adjoint problem
47 // We only have one QoI, so we don't bother checking the qois argument
48 // to see if it was requested from us
50  const QoISet & /* qois */)
51 {
52  FEMContext & c = cast_ref<FEMContext &>(context);
53 
54  FEBase * side_fe = nullptr;
55  c.get_side_fe(u_var, side_fe);
56 
57  // Element Jacobian * quadrature weights for interior integration
58  const std::vector<Real> & JxW = side_fe->get_JxW();
59 
60  // Side basis functions
61  const std::vector<std::vector<Real>> & phi = side_fe->get_phi();
62  const std::vector<Point > & q_point = side_fe->get_xyz();
63 
64  // The number of local degrees of freedom in each variable
65  const unsigned int n_u_dofs = c.n_dof_indices(1);
66 
69 
70  // Now we will build the element Jacobian and residual.
71  // Constructing the residual requires the solution and its
72  // gradient from the previous timestep. This must be
73  // calculated at each quadrature point by summing the
74  // solution degree-of-freedom values by the appropriate
75  // weight functions.
76  unsigned int n_qpoints = c.get_side_qrule().n_points();
77 
78  Number u = 0.;
79  Number C = 0.;
80 
81  // // If side is on outlet
82  if (c.has_side_boundary_id(2))
83  {
84  // Loop over all the qps on this side
85  for (unsigned int qp=0; qp != n_qpoints; qp++)
86  {
87  Real x = q_point[qp](0);
88 
89  // If side is on left outlet
90  if (x < 0.)
91  {
92  // Get u at the qp
93  u = c.side_value(0, qp);
94  C = c.side_value(3, qp);
95 
96  // Add the contribution from each basis function
97  for (unsigned int i=0; i != n_u_dofs; i++)
98  {
99  Qu(i) += JxW[qp] * -phi[i][qp] * C;
100  QC(i) += JxW[qp] * phi[i][qp] * -u;
101  }
102  } // end if
103 
104  } // end quadrature loop
105 
106  } // end if on outlet
107 }
108 
109 // This function computes the actual QoI
111  const QoISet & /* qois */)
112 {
113 
114  FEMContext & c = cast_ref<FEMContext &>(context);
115 
116  // First we get some references to cell-specific data that
117  // will be used to assemble the linear system.
118  FEBase * side_fe = nullptr;
119  c.get_side_fe(u_var, side_fe);
120 
121  // Element Jacobian * quadrature weights for interior integration
122  const std::vector<Real> & JxW = side_fe->get_JxW();
123  const std::vector<Point> & q_point = side_fe->get_xyz();
124 
125  // Loop over qp's, compute the function at each qp and add
126  // to get the QoI
127  unsigned int n_qpoints = c.get_side_qrule().n_points();
128 
129  Number dQoI_0 = 0.;
130  Number u = 0.;
131  Number C = 0.;
132 
133  // If side is on the left outlet
134  if (c.has_side_boundary_id(2))
135  {
136  //Loop over all the qps on this side
137  for (unsigned int qp=0; qp != n_qpoints; qp++)
138  {
139  Real x = q_point[qp](0);
140 
141  if (x < 0.)
142  {
143  // Get u and C at the qp
144  u = c.side_value(0, qp);
145  C = c.side_value(3, qp);
146 
147  dQoI_0 += JxW[qp] * -u * C;
148  } // end if
149  } // end quadrature loop
150  } // end if on bdry
151 
152  c.get_qois()[0] += dQoI_0;
153 }
const std::vector< Number > & get_qois() const
Const accessor for QoI vector.
Definition: diff_context.h:317
Number side_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:661
virtual void side_qoi(DiffContext &context, const QoISet &qois)
Does any work that needs to be done on side of elem in a quantity of interest assembly loop...
Definition: H-qoi.C:110
This class provides all data required for a physics package (e.g.
Definition: diff_context.h:55
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
Data structure for specifying which Quantities of Interest should be calculated in an adjoint or a pa...
Definition: qoi_set.h:45
unsigned int n_dof_indices() const
Total number of dof indices on the element.
Definition: diff_context.h:395
void init_qois(unsigned int n_qois)
Accessors for qoi and qoi_error_estimates vectors.
Definition: system.C:2371
The libMesh namespace provides an interface to certain functionality in the library.
bool has_side_boundary_id(boundary_id_type id) const
Reports if the boundary id is found on the current side.
Definition: fem_context.C:298
unsigned int variable_number(std::string_view var) const
Definition: system.C:1609
Defines a dense subvector for use in finite element computations.
const System & get_system() const
Accessor for associated system.
Definition: diff_context.h:106
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
virtual void init_qoi_count(System &sys)
Initialize system qoi.
Definition: H-qoi.C:10
virtual_for_inffe const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:303
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62
unsigned int n_points() const
Definition: quadrature.h:131
virtual_for_inffe const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:280
void get_nothing() const
Definition: fe_abstract.h:269
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void side_qoi_derivative(DiffContext &context, const QoISet &qois)
Does any work that needs to be done on side of elem in a quantity of interest derivative assembly loo...
Definition: H-qoi.C:49
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
const std::vector< DenseVector< Number > > & get_qoi_derivatives() const
Const accessor for QoI derivatives.
Definition: diff_context.h:329
This class forms the foundation from which generic finite elements may be derived.
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem. ...
Definition: fem_context.h:809
virtual void init_context(DiffContext &)
Prepares the result of a build_context() call for use.
Definition: H-qoi.C:16
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207