libMesh
Loading...
Searching...
No Matches
poisson.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/boundary_info.h"
6#include "libmesh/dirichlet_boundaries.h"
7#include "libmesh/dof_map.h"
8#include "libmesh/fe_base.h"
9#include "libmesh/fe_interface.h"
10#include "libmesh/fem_context.h"
11#include "libmesh/fem_system.h"
12#include "libmesh/quadrature.h"
13#include "libmesh/string_to_enum.h"
14#include "libmesh/mesh.h"
15#include "libmesh/parallel.h"
16#include "libmesh/quadrature.h"
17#include "libmesh/fem_context.h"
18#include "libmesh/zero_function.h"
19
20// Local includes
21#include "poisson.h"
22
23// C++ includes
24#include <memory>
25
26// Bring in everything from the libMesh namespace
27using namespace libMesh;
28
29// Function to set the Dirichlet boundary function for the adjoint dirichlet boundary
30class BdyFunction : public FunctionBase<Number>
31{
32public:
33 BdyFunction (unsigned int T_var)
34 : _T_var(T_var)
35 { this->_initialized = true; }
36
37 virtual Number operator() (const Point &, const Real = 0)
38 { libmesh_not_implemented(); }
39
40 virtual void operator() (const Point & p,
41 const Real,
42 DenseVector<Number> & output)
43 {
44 output.resize(2);
45 output.zero();
46 const Real x=p(0);
47 // Set the parabolic weighting
48 output(_T_var) = -x * (1 - x);
49 }
50
51 virtual std::unique_ptr<FunctionBase<Number>> clone() const
52 { return std::make_unique<BdyFunction>(_T_var); }
53
54private:
55 const unsigned int _T_var;
56};
57
59{
60 T_var =
61 this->add_variable ("T", static_cast<Order>(_fe_order),
62 Utility::string_to_enum<FEFamily>(_fe_family));
63
64 GetPot infile("poisson.in");
65 exact_QoI[0] = infile("QoI_0", 0.0);
66 alpha = infile("alpha", 100.0);
67
68 // The temperature is evolving, with a first order time derivative
69 this->time_evolving(T_var, 1);
70
71#ifdef LIBMESH_ENABLE_DIRICHLET
72 // Now we will set the Dirichlet boundary conditions
73
74 // For the adjoint problem, we will only set the bottom boundary to a non-zero value
75 const boundary_id_type bottom_bdry_id = 0;
76
77 // The zero function pointer for the primal all bdry bcs
79 // Boundary function for bottom bdry adjoint condition
80 BdyFunction bottom_adjoint(T_var);
81
83
84 this->get_dof_map().add_adjoint_dirichlet_boundary(DirichletBoundary ({bottom_bdry_id}, {T_var}, &bottom_adjoint), 0);
85#endif // LIBMESH_ENABLE_DIRICHLET
86
87 // Do the parent's initialization after variables are defined
88 FEMSystem::init_data();
89}
90
92{
93 FEMContext & c = cast_ref<FEMContext &>(context);
94
95 // Now make sure we have requested all the data
96 // we need to build the linear system.
97 FEBase* elem_fe = nullptr;
98 c.get_element_fe( 0, elem_fe );
99 elem_fe->get_JxW();
100 elem_fe->get_phi();
101 elem_fe->get_dphi();
102 elem_fe->get_xyz();
103
104 FEBase* side_fe = nullptr;
105 c.get_side_fe( 0, side_fe );
106
107 side_fe->get_JxW();
108 side_fe->get_phi();
109 side_fe->get_dphi();
110 side_fe->get_xyz();
111
112}
113
114#define optassert(X) {if (!(X)) libmesh_error_msg("Assertion " #X " failed.");}
115
116// Assemble the element contributions to the stiffness matrix
117bool PoissonSystem::element_time_derivative (bool request_jacobian,
118 DiffContext & context)
119{
120 // Are the jacobians specified analytically ?
121 bool compute_jacobian = request_jacobian && _analytic_jacobians;
122
123 FEMContext & c = cast_ref<FEMContext &>(context);
124
125 // First we get some references to cell-specific data that
126 // will be used to assemble the linear system.
127 FEBase* elem_fe = nullptr;
128 c.get_element_fe( 0, elem_fe );
129
130 // Element Jacobian * quadrature weights for interior integration
131 const std::vector<Real> & JxW = elem_fe->get_JxW();
132
133 // Element basis functions
134 const std::vector<std::vector<Real>> & phi = elem_fe->get_phi();
135 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
136
137 // Quadrature point locations
138 const std::vector<Point > & q_point = elem_fe->get_xyz();
139
140 // The number of local degrees of freedom in each variable
141 const unsigned int n_T_dofs = c.n_dof_indices(0);
142
143 // The subvectors and submatrices we need to fill:
146
147 // Now we will build the element Jacobian and residual.
148 // Constructing the residual requires the solution and its
149 // gradient from the previous timestep. This must be
150 // calculated at each quadrature point by summing the
151 // solution degree-of-freedom values by the appropriate
152 // weight functions.
153 unsigned int n_qpoints = c.get_element_qrule().n_points();
154
155 for (unsigned int qp=0; qp != n_qpoints; qp++)
156 {
157 // Compute the solution gradient at the Newton iterate
158 Gradient grad_T = c.interior_gradient(0, qp);
159
160 // Location of the current qp
161 const Real x = q_point[qp](0);
162 const Real y = q_point[qp](1);
163
164 // Forcing function
165 Real f = -alpha * ( ( (- 4 * alpha * alpha) * exp(-alpha*x) * y * (1 - y) ) + ( -8 + ( 8 * exp(-alpha*x) ) + ( 8 * ( 1 - exp(-alpha) )* x) ) );
166
167 // The residual contribution from this element
168 for (unsigned int i=0; i != n_T_dofs; i++)
169 F(i) += JxW[qp] * ( (f * phi[i][qp]) - alpha*(grad_T * dphi[i][qp]) ) ;
171 for (unsigned int i=0; i != n_T_dofs; i++)
172 for (unsigned int j=0; j != n_T_dofs; ++j)
173 // The analytic jacobian
174 K(i,j) += JxW[qp] * ( -alpha*(dphi[i][qp] * dphi[j][qp]) );
175 } // end of the quadrature point qp-loop
176
177 return compute_jacobian;
178}
179
180// Override the default DiffSystem postprocess function to compute the
181// approximations to the QoIs
183{
184 // Reset the array holding the computed QoIs
185 computed_QoI[0] = 0.0;
186
187 FEMSystem::postprocess();
188
189 this->comm().sum(computed_QoI[0]);
190}
virtual Number operator()(const Point &, const Real=0)
virtual std::unique_ptr< FunctionBase< Number > > clone() const
Definition poisson.C:51
const unsigned int _T_var
Definition poisson.C:55
BdyFunction(unsigned int T_var)
Definition poisson.C:33
bool _analytic_jacobians
Definition poisson.h:76
unsigned int _fe_order
Definition poisson.h:73
Number exact_QoI[1]
Definition poisson.h:69
virtual void init_context(DiffContext &context)
Definition poisson.C:91
virtual void postprocess(void)
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides.
Definition poisson.C:182
virtual bool element_time_derivative(bool request_jacobian, DiffContext &context)
Adds the time derivative contribution on elem to elem_residual.
Definition poisson.C:117
std::string _fe_family
Definition poisson.h:72
unsigned int T_var
Definition poisson.h:61
virtual void init_data()
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used.
Definition poisson.C:58
Number computed_QoI[1]
Definition poisson.h:65
Defines a dense submatrix for use in Finite Element-type computations.
Defines a dense subvector for use in finite element computations.
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
virtual void zero() override final
Set every element in the vector to 0.
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.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
void add_adjoint_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary, unsigned int q)
Adds a copy of the specified Dirichlet boundary to the system, corresponding to the adjoint problem d...
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
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.
Base class for functors that can be evaluated at a point and (optionally) time.
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
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
const DofMap & get_dof_map() const
Definition system.h:2417
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
ConstFunction that simply returns 0.
The libMesh namespace provides an interface to certain functionality in the library.
int8_t boundary_id_type
Definition id_types.h:51
const Number zero
.
Definition libmesh.h:297
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