20 #include "libmesh/getpot.h"
22 #include "heatsystem.h"
24 #include "libmesh/fe_base.h"
25 #include "libmesh/fe_interface.h"
26 #include "libmesh/fem_context.h"
27 #include "libmesh/mesh.h"
28 #include "libmesh/quadrature.h"
29 #include "libmesh/string_to_enum.h"
30 #include "libmesh/system.h"
31 #include "libmesh/equation_systems.h"
32 #include "libmesh/zero_function.h"
33 #include "libmesh/dirichlet_boundaries.h"
34 #include "libmesh/dof_map.h"
39 Utility::string_to_enum<FEFamily>(
_fe_family));
43 std::ifstream i(
"heat.in");
45 libmesh_error_msg(
'[' << this->
processor_id() <<
"] Can't find heat.in; exiting early.");
47 GetPot infile(
"heat.in");
48 _k = infile(
"k", 1.0);
60 std::set<boundary_id_type> all_bdys(all_ids, all_ids+(2*2));
62 std::vector<unsigned int> T_only(1,
T_var);
64 ZeroFunction<Number>
zero;
66 #ifdef LIBMESH_ENABLE_DIRICHLET
70 (DirichletBoundary (all_bdys, T_only,
zero,
74 FEMSystem::init_data();
81 FEMContext & c = cast_ref<FEMContext &>(context);
83 FEBase * elem_fe =
nullptr;
84 c.get_element_fe(0, elem_fe);
96 const System & sys = c.get_system();
99 NumericVector<Number> & adjoint_solution =
100 const_cast<System &>(sys).get_adjoint_solution(0);
103 c.add_localized_vector(adjoint_solution, sys);
106 FEMSystem::init_context(context);
109 #define optassert(X) {if (!(X)) libmesh_error_msg("Assertion " #X " failed.");}
113 DiffContext & context)
117 FEMContext & c = cast_ref<FEMContext &>(context);
121 FEBase * elem_fe =
nullptr;
122 c.get_element_fe(0, elem_fe);
125 const std::vector<Real> & JxW = elem_fe->get_JxW();
128 const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();
131 const unsigned int n_u_dofs = c.n_dof_indices(0);
134 DenseSubMatrix<Number> & K = c.get_elem_jacobian(0, 0);
135 DenseSubVector<Number> & F = c.get_elem_residual(0);
143 unsigned int n_qpoints = c.get_element_qrule().n_points();
145 for (
unsigned int qp=0; qp != n_qpoints; qp++)
148 Gradient grad_T = c.interior_gradient(0, qp);
150 for (
unsigned int i=0; i != n_u_dofs; i++)
151 F(i) += JxW[qp] * -
parameters[0] * (grad_T * dphi[i][qp]);
153 for (
unsigned int i=0; i != n_u_dofs; i++)
154 for (
unsigned int j=0; j != n_u_dofs; ++j)
155 K(i,j) += JxW[qp] * -
parameters[0] * (dphi[i][qp] * dphi[j][qp]);
166 for (std::size_t j=0, Np = parameters_in.size(); j != Np; ++j)
168 Number old_parameter = *parameters_in[j];
170 *parameters_in[j] = old_parameter -
dp;
176 std::unique_ptr<NumericVector<Number>> R_minus = this->
rhs->
clone();
182 *parameters_in[j] = old_parameter +
dp;
188 std::unique_ptr<NumericVector<Number>> R_plus = this->
rhs->
clone();
192 *parameters_in[j] = old_parameter;