Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
L-shaped.C
Go to the documentation of this file.
1 // This is where we define the assembly of the Laplace system
2 
3 // General libMesh includes
4 #include "libmesh/getpot.h"
5 #include "libmesh/fe_base.h"
6 #include "libmesh/quadrature.h"
7 #include "libmesh/string_to_enum.h"
8 #include "libmesh/parallel.h"
9 #include "libmesh/fem_context.h"
10 
11 // Local includes
12 #include "L-shaped.h"
13 
14 // Bring in everything from the libMesh namespace
15 using namespace libMesh;
16 
18 {
19  unsigned int T_var =
20  this->add_variable ("T", static_cast<Order>(_fe_order),
21  Utility::string_to_enum<FEFamily>(_fe_family));
22 
23  GetPot infile("l-shaped.in");
24  exact_QoI[0] = infile("QoI_0", 0.0);
25  exact_QoI[1] = infile("QoI_1", 0.0);
26 
27  // Do the parent's initialization after variables are defined
29 
30  // The temperature is evolving, with a first order time derivative
31  this->time_evolving(T_var, 1);
32 }
33 
35 {
36  FEMContext & c = cast_ref<FEMContext &>(context);
37 
38  // Now make sure we have requested all the data
39  // we need to build the linear system.
40  FEBase * elem_fe = nullptr;
41  c.get_element_fe(0, elem_fe);
42  elem_fe->get_JxW();
43  elem_fe->get_phi();
44  elem_fe->get_dphi();
45  elem_fe->get_xyz();
46 
47  FEBase * side_fe = nullptr;
48  c.get_side_fe(0, side_fe);
49 
50  side_fe->get_JxW();
51  side_fe->get_phi();
52  side_fe->get_dphi();
53 }
54 
55 #define optassert(X) {if (!(X)) libmesh_error_msg("Assertion " #X " failed.");}
56 
57 // Assemble the element contributions to the stiffness matrix
58 bool LaplaceSystem::element_time_derivative (bool request_jacobian,
59  DiffContext & context)
60 {
61  // Are the jacobians specified analytically ?
62  bool compute_jacobian = request_jacobian && _analytic_jacobians;
63 
64  FEMContext & c = cast_ref<FEMContext &>(context);
65 
66  // First we get some references to cell-specific data that
67  // will be used to assemble the linear system.
68  FEBase * elem_fe = nullptr;
69  c.get_element_fe(0, elem_fe);
70 
71  // Element Jacobian * quadrature weights for interior integration
72  const std::vector<Real> & JxW = elem_fe->get_JxW();
73 
74  // Element basis functions
75  const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
76 
77  // The number of local degrees of freedom in each variable
78  const unsigned int n_T_dofs = c.n_dof_indices(0);
79 
80  // The subvectors and submatrices we need to fill:
83 
84  // Now we will build the element Jacobian and residual.
85  // Constructing the residual requires the solution and its
86  // gradient from the previous timestep. This must be
87  // calculated at each quadrature point by summing the
88  // solution degree-of-freedom values by the appropriate
89  // weight functions.
90  unsigned int n_qpoints = c.get_element_qrule().n_points();
91 
92  for (unsigned int qp=0; qp != n_qpoints; qp++)
93  {
94  // Compute the solution gradient at the Newton iterate
95  Gradient grad_T = c.interior_gradient(0, qp);
96 
97  // The residual contribution from this element
98  for (unsigned int i=0; i != n_T_dofs; i++)
99  F(i) += JxW[qp] * (grad_T * dphi[i][qp]);
100  if (compute_jacobian)
101  for (unsigned int i=0; i != n_T_dofs; i++)
102  for (unsigned int j=0; j != n_T_dofs; ++j)
103  // The analytic jacobian
104  K(i,j) += JxW[qp] * (dphi[i][qp] * dphi[j][qp]);
105  } // end of the quadrature point qp-loop
106 
107  return compute_jacobian;
108 }
109 
110 // Set Dirichlet bcs, side contributions to global stiffness matrix
111 bool LaplaceSystem::side_constraint (bool request_jacobian,
112  DiffContext & context)
113 {
114  // Are the jacobians specified analytically ?
115  bool compute_jacobian = request_jacobian && _analytic_jacobians;
116 
117  FEMContext & c = cast_ref<FEMContext &>(context);
118 
119  // First we get some references to cell-specific data that
120  // will be used to assemble the linear system.
121  FEBase * side_fe = nullptr;
122  c.get_side_fe(0, side_fe);
123 
124  // Element Jacobian * quadrature weights for interior integration
125  const std::vector<Real> & JxW = side_fe->get_JxW();
126 
127  // Side basis functions
128  const std::vector<std::vector<Real>> & phi = side_fe->get_phi();
129 
130  // Side Quadrature points
131  const std::vector<Point > & qside_point = side_fe->get_xyz();
132 
133  // The number of local degrees of freedom in each variable
134  const unsigned int n_T_dofs = c.n_dof_indices(0);
135 
136  // The subvectors and submatrices we need to fill:
139 
140  unsigned int n_qpoints = c.get_side_qrule().n_points();
141 
142  const Real penalty = 1./(TOLERANCE*TOLERANCE);
143 
144  for (unsigned int qp=0; qp != n_qpoints; qp++)
145  {
146  // Compute the solution at the old Newton iterate
147  Number T = c.side_value(0, qp);
148 
149  // We get the Dirichlet bcs from the exact solution
150  Number u_dirichlet = exact_solution (qside_point[qp]);
151 
152  // The residual from the boundary terms, penalize non-zero temperature
153  for (unsigned int i=0; i != n_T_dofs; i++)
154  F(i) += JxW[qp] * penalty * (T - u_dirichlet) * phi[i][qp];
155  if (compute_jacobian)
156  for (unsigned int i=0; i != n_T_dofs; i++)
157  for (unsigned int j=0; j != n_T_dofs; ++j)
158  // The analytic jacobian
159  K(i,j) += JxW[qp] * penalty * phi[i][qp] * phi[j][qp];
160 
161  } // end of the quadrature point qp-loop
162 
163  return compute_jacobian;
164 }
165 
166 // Override the default DiffSystem postprocess function to compute the
167 // approximations to the QoIs
169 {
170  // Reset the array holding the computed QoIs
171  computed_QoI[0] = 0.0;
172  computed_QoI[1] = 0.0;
173 
175 
176  this->comm().sum(computed_QoI[0]);
177 
178  this->comm().sum(computed_QoI[1]);
179 
180 }
181 
182 // The exact solution to the singular problem,
183 // u_exact = r^(2/3)*sin(2*theta/3). We use this to set the Dirichlet boundary conditions
184 Number LaplaceSystem::exact_solution(const Point & p)// xyz location
185 {
186  const Real x1 = p(0);
187  const Real x2 = p(1);
188 
189  Real theta = atan2(x2, x1);
190 
191  // Make sure 0 <= theta <= 2*pi
192  if (theta < 0)
193  theta += 2. * libMesh::pi;
194 
195  return pow(x1*x1 + x2*x2, 1./3.)*sin(2./3.*theta);
196 
197 }
virtual void init_context(DiffContext &context)
Definition: L-shaped.C:34
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
Number side_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:661
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
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
static constexpr Real TOLERANCE
unsigned int n_dof_indices() const
Total number of dof indices on the element.
Definition: diff_context.h:395
virtual bool element_time_derivative(bool request_jacobian, DiffContext &context)
Adds the time derivative contribution on elem to elem_residual.
Definition: L-shaped.C:58
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.
void compute_jacobian(const NumericVector< Number > &, SparseMatrix< Number > &J, NonlinearImplicitSystem &system)
Definition: assembly.C:315
Defines a dense subvector for use in finite element computations.
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition: fe_base.h:230
Gradient interior_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:467
T pow(const T &x)
Definition: utility.h:328
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
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 void postprocess() override
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides...
Definition: fem_system.C:1127
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
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
LaplaceExactSolution exact_solution
virtual bool side_constraint(bool request_jacobian, DiffContext &context)
Adds the constraint contribution on side of elem to elem_residual.
Definition: L-shaped.C:111
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual void init_data()
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used...
Definition: L-shaped.C:17
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides...
Definition: L-shaped.C:168
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 QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem. ...
Definition: fem_context.h:809
const Real pi
.
Definition: libmesh.h:299
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207