libMesh
L2system.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "L2system.h"
19 
20 #include "libmesh/elem.h"
21 #include "libmesh/fe_base.h"
22 #include "libmesh/fe_interface.h"
23 #include "libmesh/fem_context.h"
24 #include "libmesh/getpot.h"
25 #include "libmesh/mesh.h"
26 #include "libmesh/quadrature.h"
27 #include "libmesh/string_to_enum.h"
28 #include "libmesh/utility.h"
29 
30 using namespace libMesh;
31 
33 
35 {
36  this->add_variable ("u", static_cast<Order>(_fe_order),
37  Utility::string_to_enum<FEFamily>(_fe_family));
38 
39  // Do the parent's initialization after variables are defined
41 }
42 
43 
44 
46 {
47  FEMContext & c = cast_ref<FEMContext &>(context);
48 
49  FEBase * my_fe = nullptr;
50 
51  // Now make sure we have requested all the data
52  // we need to build the L2 system.
53 
54  // We might have a multi-dimensional mesh
55  const std::set<unsigned char> & elem_dims =
56  c.elem_dimensions();
57 
58  for (const auto & dim : elem_dims)
59  {
60  c.get_element_fe( 0, my_fe, dim );
61 
62  my_fe->get_JxW();
63  my_fe->get_phi();
64  my_fe->get_xyz();
65 
66  if (this->_hilbert_order > 0)
67  my_fe->get_dphi();
68 
69  c.get_side_fe( 0, my_fe, dim );
70  my_fe->get_nothing();
71  }
72 
73  // Build a corresponding context for the input system if we haven't
74  // already
75  auto & input_context = input_contexts[&c];
76  if (input_system && !input_context)
77  {
78  input_context = std::make_unique<FEMContext>(*input_system);
79 
80  libmesh_assert(_goal_func.get());
81  _goal_func->init_context(*input_context);
82  }
83 
84  FEMSystem::init_context(context);
85 }
86 
87 
88 bool HilbertSystem::element_time_derivative (bool request_jacobian,
89  DiffContext & context)
90 {
91  FEMContext & c = cast_ref<FEMContext &>(context);
92 
93  const Elem & elem = c.get_elem();
94 
95  if (!_subdomains_list.empty() &&
96  !_subdomains_list.count(elem.subdomain_id()))
97  return request_jacobian;
98 
99  // First we get some references to cell-specific data that
100  // will be used to assemble the linear system.
101 
102  // Element Jacobian * quadrature weights for interior integration
103  const std::vector<Real> & JxW = c.get_element_fe(0)->get_JxW();
104 
105  const std::vector<std::vector<Real>> & phi = c.get_element_fe(0)->get_phi();
106 
107  const std::vector<Point> & xyz = c.get_element_fe(0)->get_xyz();
108 
109  // The number of local degrees of freedom in each variable
110  const unsigned int n_u_dofs = c.n_dof_indices(0);
111 
112  // The subvectors and submatrices we need to fill:
115 
116  unsigned int n_qpoints = c.get_element_qrule().n_points();
117 
118  FEMContext & input_c = *libmesh_map_find(input_contexts, &c);
119  if (input_system)
120  {
121  input_c.pre_fe_reinit(*input_system, &elem);
122  input_c.elem_fe_reinit();
123  }
124 
125  for (unsigned int qp=0; qp != n_qpoints; qp++)
126  {
127  const Number u = c.interior_value(0, qp);
128  const Number ufunc = (*_goal_func)(input_c, xyz[qp]);
129  const Number err_u = u - ufunc;
130 
131  for (unsigned int i=0; i != n_u_dofs; i++)
132  F(i) += JxW[qp] * (err_u * phi[i][qp]);
133 
134  if (_hilbert_order > 0)
135  {
136  const std::vector<std::vector<RealGradient>> & dphi =
137  c.get_element_fe(0)->get_dphi();
138 
139  const Gradient grad_u = c.interior_gradient(0, qp);
140  Gradient ufuncgrad = (*_goal_grad)(input_c, xyz[qp]);
141  const Gradient err_grad_u = grad_u - ufuncgrad;
142 
143  for (unsigned int i=0; i != n_u_dofs; i++)
144  F(i) += JxW[qp] * (err_grad_u * dphi[i][qp]);
145  }
146 
147  if (request_jacobian)
148  {
149  const Number JxWxD = JxW[qp] *
151 
152  for (unsigned int i=0; i != n_u_dofs; i++)
153  for (unsigned int j=0; j != n_u_dofs; ++j)
154  K(i,j) += JxWxD * (phi[i][qp] * phi[j][qp]);
155 
156  if (_hilbert_order > 0)
157  {
158  const std::vector<std::vector<RealGradient>> & dphi =
159  c.get_element_fe(0)->get_dphi();
160 
161  for (unsigned int i=0; i != n_u_dofs; i++)
162  for (unsigned int j=0; j != n_u_dofs; ++j)
163  K(i,j) += JxWxD * (dphi[i][qp] * dphi[j][qp]);
164  }
165  }
166  } // end of the quadrature point qp-loop
167 
168  return request_jacobian;
169 }
Real get_elem_solution_derivative() const
The derivative of the current elem_solution w.r.t.
Definition: diff_context.h:432
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
Number interior_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:412
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
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1683
const Elem & get_elem() const
Accessor for current Elem object.
Definition: fem_context.h:908
unsigned int dim
virtual void init_context(DiffContext &) override
Definition: fem_system.C:1370
unsigned int n_dof_indices() const
Total number of dof indices on the element.
Definition: diff_context.h:395
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
virtual bool element_time_derivative(bool request_jacobian, libMesh::DiffContext &context)
Adds the time derivative contribution on elem to elem_residual.
Definition: L2system.C:88
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
Definition: fem_context.C:1477
Defines a dense subvector for use in finite element computations.
Gradient interior_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:467
Defines a dense submatrix for use in Finite Element-type computations.
virtual void init_data() override
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used...
Definition: fem_system.C:873
libmesh_assert(ctx)
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
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:242
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
virtual void init_data()
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used...
Definition: L2system.C:34
This class forms the foundation from which generic finite elements may be derived.
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 std::set< unsigned char > & elem_dimensions() const
Definition: fem_context.h:951
virtual void init_context(libMesh::DiffContext &context)
Definition: L2system.C:45