libMesh
Loading...
Searching...
No Matches
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
15using 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
28 FEMSystem::init_data();
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
58bool 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]);
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
111bool 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];
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
174 FEMSystem::postprocess();
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
184Number 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}
std::string _fe_family
Definition L-shaped.h:84
bool _analytic_jacobians
Definition L-shaped.h:88
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
Number exact_QoI[2]
Definition L-shaped.h:81
LaplaceExactSolution exact_solution
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides.
Definition L-shaped.C:168
Number computed_QoI[2]
Definition L-shaped.h:77
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
unsigned int _fe_order
Definition L-shaped.h:85
virtual void init_context(DiffContext &context)
Definition L-shaped.C:34
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
Defines a dense submatrix for use in Finite Element-type computations.
Defines a dense subvector for use in finite element computations.
This class provides all data required for a physics package (e.g.
unsigned int n_dof_indices() const
Total number of dof indices on the element.
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
virtual void time_evolving(unsigned int var, unsigned int order)
Tells the DiffSystem that variable var is evolving with respect to time.
virtual_for_inffe const std::vector< Real > & get_JxW() const
virtual_for_inffe const std::vector< Point > & get_xyz() const
This class forms the foundation from which generic finite elements may be derived.
Definition fe_base.h:86
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition fe_base.h:207
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition fe_base.h:230
This class provides all data required for a physics package (e.g.
Definition fem_context.h:63
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...
Gradient interior_gradient(unsigned int var, unsigned int qp) const
Number side_value(unsigned int var, unsigned int qp) const
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
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.
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem.
const Parallel::Communicator & comm() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
unsigned int n_points() const
Definition quadrature.h:131
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition system.C:1344
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.
const Real pi
.
Definition libmesh.h:292
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void compute_jacobian(const NumericVector< Number > &, SparseMatrix< Number > &J, NonlinearImplicitSystem &system)
Definition assembly.C:315