GRINS-0.6.0
heat_transfer_adjoint_stab.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 
26 // This class
27 #include "grins/assembly_context.h"
30 
31 // libMesh
32 #include "libmesh/quadrature.h"
33 
34 namespace GRINS
35 {
36 
37  template<class K>
39  const GetPot& input )
40  : HeatTransferStabilizationBase<K>(physics_name,input)
41  {
42  return;
43  }
44 
45  template<class K>
47  {
48  return;
49  }
50 
51  template<class K>
53  AssemblyContext& context,
54  CachedValues& /*cache*/ )
55  {
56 #ifdef GRINS_USE_GRVY_TIMERS
57  this->_timer->BeginTimer("HeatTransferAdjointStabilization::element_time_derivative");
58 #endif
59 
60  // The number of local degrees of freedom in each variable.
61  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T_var()).size();
62  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u_var()).size();
63 
64  // Element Jacobian * quadrature weights for interior integration.
65  const std::vector<libMesh::Real> &JxW =
66  context.get_element_fe(this->_temp_vars.T_var())->get_JxW();
67 
68  const std::vector<std::vector<libMesh::Real> >& u_phi =
69  context.get_element_fe(this->_flow_vars.u_var())->get_phi();
70 
71  const std::vector<std::vector<libMesh::Real> >& T_phi =
72  context.get_element_fe(this->_temp_vars.T_var())->get_phi();
73 
74  const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
75  context.get_element_fe(this->_temp_vars.T_var())->get_dphi();
76 
77  const std::vector<std::vector<libMesh::RealTensor> >& T_hessphi =
78  context.get_element_fe(this->_temp_vars.T_var())->get_d2phi();
79 
80  /*
81  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u_var()).size();
82 
83  const std::vector<std::vector<libMesh::Real> >& u_phi =
84  context.get_element_fe(this->_flow_vars.u_var())->get_phi();
85 
86  libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u_var()); // R_{p}
87  libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v_var()); // R_{p}
88  libMesh::DenseSubVector<libMesh::Number> *Fw = NULL;
89  if(this->_dim == 3)
90  {
91  Fw = &context.get_elem_residual(this->_flow_vars.w_var()); // R_{w}
92  }
93  */
94 
95  libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T_var()); // R_{T}
96  libMesh::DenseSubMatrix<libMesh::Number> &KTT =
97  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_temp_vars.T_var()); // J_{TT}
98  libMesh::DenseSubMatrix<libMesh::Number> &KTu =
99  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_flow_vars.u_var()); // J_{Tu}
100  libMesh::DenseSubMatrix<libMesh::Number> &KTv =
101  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_flow_vars.v_var()); // J_{Tv}
102  libMesh::DenseSubMatrix<libMesh::Number> *KTw = NULL;
103 
104  if(this->_dim == 3)
105  {
106  KTw = &context.get_elem_jacobian
107  (this->_temp_vars.T_var(), this->_flow_vars.w_var()); // J_{Tw}
108  }
109 
110  unsigned int n_qpoints = context.get_element_qrule().n_points();
111 
112  for (unsigned int qp=0; qp != n_qpoints; qp++)
113  {
114  libMesh::FEBase* fe = context.get_element_fe(this->_temp_vars.T_var());
115 
116  libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
117  libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
118 
119  libMesh::RealGradient U( context.interior_value( this->_flow_vars.u_var(), qp ),
120  context.interior_value( this->_flow_vars.v_var(), qp ) );
121  if( this->_dim == 3 )
122  {
123  U(2) = context.interior_value( this->_flow_vars.w_var(), qp );
124  }
125 
126  //libMesh::RealGradient grad_T = context.interior_gradient( this->_temp_vars.T_var(), qp );
127 
128  libMesh::Real tau_E, RE_s;
129  libMesh::Real d_tau_E_dT_rho, d_RE_s_dT;
130  libMesh::Gradient d_tau_E_dU, d_RE_s_dgradT, d_RE_s_dU;
131  libMesh::Tensor d_RE_s_dhessT;
132 
133  // Compute the conductivity at this qp
134  libMesh::Real _k_qp = this->_k(context, qp);
135 
136  if (compute_jacobian)
137  {
138  this->_stab_helper.compute_tau_energy_and_derivs
139  ( context, G, this->_rho, this->_Cp, _k_qp, U,
140  tau_E, d_tau_E_dT_rho, d_tau_E_dU, this->_is_steady );
141  this->_stab_helper.compute_res_energy_steady_and_derivs
142  ( context, qp, this->_rho, this->_Cp, _k_qp,
143  RE_s, d_RE_s_dT, d_RE_s_dgradT, d_RE_s_dhessT,
144  d_RE_s_dU );
145  }
146  else
147  {
148  tau_E = this->_stab_helper.compute_tau_energy
149  ( context, G, this->_rho, this->_Cp, _k_qp, U, this->_is_steady );
150 
151  RE_s = this->_stab_helper.compute_res_energy_steady
152  ( context, qp, this->_rho, this->_Cp, _k_qp );
153  }
154 
155  /*
156  for (unsigned int i=0; i != n_u_dofs; i++)
157  {
158  Fu(i) += -tau_E*RE_s*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(0)*JxW[qp];
159  Fv(i) += -tau_E*RE_s*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(1)*JxW[qp];
160  if( this->_dim == 3 )
161  {
162  (*Fw)(i) += -tau_E*RE_s*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(2)*JxW[qp];
163  }
164  }
165  */
166 
167  for (unsigned int i=0; i != n_T_dofs; i++)
168  {
169  FT(i) += -tau_E*RE_s*( this->_rho*this->_Cp*U*T_gradphi[i][qp]
170  + _k_qp*(T_hessphi[i][qp](0,0) + T_hessphi[i][qp](1,1) + T_hessphi[i][qp](2,2))
171  )*JxW[qp];
172  if (compute_jacobian)
173  {
174  for (unsigned int j=0; j != n_T_dofs; ++j)
175  {
176  KTT(i,j) += -tau_E*
177  (d_RE_s_dT*T_phi[j][qp] +
178  d_RE_s_dgradT*T_gradphi[j][qp] +
179  d_RE_s_dhessT.contract(T_hessphi[j][qp])
180  ) *
181  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
182  + _k_qp*(T_hessphi[i][qp](0,0) +
183  T_hessphi[i][qp](1,1) +
184  T_hessphi[i][qp](2,2))
185  )*JxW[qp]
186  * context.get_fixed_solution_derivative();
187  }
188  for (unsigned int j=0; j != n_u_dofs; ++j)
189  {
190  KTu(i,j) += -tau_E*RE_s*
191  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](0) )*JxW[qp]
192  * context.get_fixed_solution_derivative();
193  KTu(i,j) +=
194  -(tau_E*d_RE_s_dU(0)+d_tau_E_dU(0)*RE_s)*u_phi[j][qp]*
195  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
196  + _k_qp*(T_hessphi[i][qp](0,0) +
197  T_hessphi[i][qp](1,1) +
198  T_hessphi[i][qp](2,2))
199  )*JxW[qp]
200  * context.get_fixed_solution_derivative();
201  KTv(i,j) += -tau_E*RE_s*
202  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](1) )*JxW[qp]
203  * context.get_fixed_solution_derivative();
204  KTv(i,j) +=
205  -(tau_E*d_RE_s_dU(1)+d_tau_E_dU(1)*RE_s)*u_phi[j][qp]*
206  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
207  + _k_qp*(T_hessphi[i][qp](0,0) +
208  T_hessphi[i][qp](1,1) +
209  T_hessphi[i][qp](2,2))
210  )*JxW[qp]
211  * context.get_fixed_solution_derivative();
212  }
213  if(this->_dim == 3)
214  {
215  for (unsigned int j=0; j != n_u_dofs; ++j)
216  {
217  (*KTw)(i,j) += -tau_E*RE_s*
218  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](2) )*JxW[qp]
219  * context.get_fixed_solution_derivative();
220  (*KTw)(i,j) +=
221  -(tau_E*d_RE_s_dU(2)+d_tau_E_dU(2)*RE_s)*u_phi[j][qp]*
222  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
223  + _k_qp*(T_hessphi[i][qp](0,0) +
224  T_hessphi[i][qp](1,1) +
225  T_hessphi[i][qp](2,2))
226  )*JxW[qp]
227  * context.get_fixed_solution_derivative();
228  }
229  }
230  }
231  }
232  }
233 
234 #ifdef GRINS_USE_GRVY_TIMERS
235  this->_timer->EndTimer("HeatTransferAdjointStabilization::element_time_derivative");
236 #endif
237  return;
238  }
239 
240  template<class K>
242  AssemblyContext& context,
243  CachedValues& /*cache*/ )
244  {
245 #ifdef GRINS_USE_GRVY_TIMERS
246  this->_timer->BeginTimer("HeatTransferAdjointStabilization::mass_residual");
247 #endif
248 
249  // The number of local degrees of freedom in each variable.
250  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T_var()).size();
251  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u_var()).size();
252 
253  // Element Jacobian * quadrature weights for interior integration.
254  const std::vector<libMesh::Real> &JxW =
255  context.get_element_fe(this->_temp_vars.T_var())->get_JxW();
256 
257  const std::vector<std::vector<libMesh::Real> >& u_phi =
258  context.get_element_fe(this->_flow_vars.u_var())->get_phi();
259 
260  const std::vector<std::vector<libMesh::Real> >& T_phi =
261  context.get_element_fe(this->_temp_vars.T_var())->get_phi();
262 
263  const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
264  context.get_element_fe(this->_temp_vars.T_var())->get_dphi();
265 
266  const std::vector<std::vector<libMesh::RealTensor> >& T_hessphi =
267  context.get_element_fe(this->_temp_vars.T_var())->get_d2phi();
268 
269  /*
270  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u_var()).size();
271 
272  const std::vector<std::vector<libMesh::Real> >& u_phi =
273  context.get_element_fe(this->_flow_vars.u_var())->get_phi();
274 
275  libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u_var()); // R_{p}
276  libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v_var()); // R_{p}
277  libMesh::DenseSubVector<libMesh::Number> *Fw = NULL;
278  if(this->_dim == 3)
279  {
280  Fw = &context.get_elem_residual(this->_flow_vars.w_var()); // R_{w}
281  }
282  */
283 
284  libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T_var()); // R_{T}
285  libMesh::DenseSubMatrix<libMesh::Number> &KTT =
286  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_temp_vars.T_var()); // J_{TT}
287  libMesh::DenseSubMatrix<libMesh::Number> &KTu =
288  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_flow_vars.u_var()); // J_{Tu}
289  libMesh::DenseSubMatrix<libMesh::Number> &KTv =
290  context.get_elem_jacobian(this->_temp_vars.T_var(), this->_flow_vars.v_var()); // J_{Tv}
291  libMesh::DenseSubMatrix<libMesh::Number> *KTw = NULL;
292 
293  if(this->_dim == 3)
294  {
295  KTw = &context.get_elem_jacobian
296  (this->_temp_vars.T_var(), this->_flow_vars.w_var()); // J_{Tw}
297  }
298 
299  unsigned int n_qpoints = context.get_element_qrule().n_points();
300 
301  for (unsigned int qp=0; qp != n_qpoints; qp++)
302  {
303  libMesh::FEBase* fe = context.get_element_fe(this->_temp_vars.T_var());
304 
305  libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
306  libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
307 
308  libMesh::RealGradient U( context.fixed_interior_value( this->_flow_vars.u_var(), qp ),
309  context.fixed_interior_value( this->_flow_vars.v_var(), qp ) );
310  if( this->_dim == 3 )
311  U(2) = context.fixed_interior_value( this->_flow_vars.w_var(), qp );
312 
313  //libMesh::RealGradient grad_T = context.fixed_interior_gradient( this->_temp_vars.T_var(), qp );
314 
315  libMesh::Real tau_E, RE_t;
316  libMesh::Real d_tau_E_d_rho, d_RE_t_dT;
317  libMesh::Gradient d_tau_E_dU;
318 
319  // Compute the conductivity at this qp
320  libMesh::Real _k_qp = this->_k(context, qp);
321 
322  if (compute_jacobian)
323  {
324  this->_stab_helper.compute_tau_energy_and_derivs
325  ( context, G, this->_rho, this->_Cp, _k_qp, U,
326  tau_E, d_tau_E_d_rho, d_tau_E_dU, false );
327  this->_stab_helper.compute_res_energy_transient_and_derivs
328  ( context, qp, this->_rho, this->_Cp,
329  RE_t, d_RE_t_dT );
330  }
331  else
332  {
333  tau_E = this->_stab_helper.compute_tau_energy
334  ( context, G, this->_rho, this->_Cp, _k_qp, U, false );
335 
336  RE_t = this->_stab_helper.compute_res_energy_transient
337  ( context, qp, this->_rho, this->_Cp );
338  }
339 
340 
341  /*
342  for (unsigned int i=0; i != n_u_dofs; i++)
343  {
344  Fu(i) += -tau_E*RE_t*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(0)*JxW[qp];
345  Fv(i) += -tau_E*RE_t*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(1)*JxW[qp];
346  if( this->_dim == 3 )
347  {
348  (*Fw)(i) += -tau_E*RE_t*this->_rho*this->_Cp*u_phi[i][qp]*grad_T(2)*JxW[qp];
349  }
350  }
351  */
352 
353  for (unsigned int i=0; i != n_T_dofs; i++)
354  {
355  FT(i) -= tau_E*RE_t*( this->_rho*this->_Cp*U*T_gradphi[i][qp]
356  + _k_qp*(T_hessphi[i][qp](0,0) + T_hessphi[i][qp](1,1) + T_hessphi[i][qp](2,2))
357  )*JxW[qp];
358  if (compute_jacobian)
359  {
360  const libMesh::Real fixed_deriv =
361  context.get_fixed_solution_derivative();
362 
363  for (unsigned int j=0; j != n_T_dofs; ++j)
364  {
365  KTT(i,j) -=
366  (tau_E*d_RE_t_dT)*T_phi[j][qp]*
367  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
368  + _k_qp*(T_hessphi[i][qp](0,0) +
369  T_hessphi[i][qp](1,1) +
370  T_hessphi[i][qp](2,2))
371  )*JxW[qp];
372  }
373  for (unsigned int j=0; j != n_u_dofs; ++j)
374  {
375  KTu(i,j) -=
376  d_tau_E_dU(0)*u_phi[j][qp]*RE_t*
377  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
378  + _k_qp*(T_hessphi[i][qp](0,0) +
379  T_hessphi[i][qp](1,1) +
380  T_hessphi[i][qp](2,2))
381  )*fixed_deriv*JxW[qp];
382  KTu(i,j) -=
383  tau_E*RE_t*
384  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](0)*fixed_deriv
385  )*JxW[qp];
386  KTv(i,j) -=
387  d_tau_E_dU(1)*u_phi[j][qp]*RE_t*
388  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
389  + _k_qp*(T_hessphi[i][qp](0,0) +
390  T_hessphi[i][qp](1,1) +
391  T_hessphi[i][qp](2,2))
392  )*fixed_deriv*JxW[qp];
393  KTv(i,j) -=
394  tau_E*RE_t*
395  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](1)*fixed_deriv
396  )*JxW[qp];
397  }
398  if(this->_dim == 3)
399  {
400  for (unsigned int j=0; j != n_u_dofs; ++j)
401  {
402  (*KTw)(i,j) -=
403  d_tau_E_dU(2)*u_phi[j][qp]*RE_t*
404  ( this->_rho*this->_Cp*U*T_gradphi[i][qp]
405  + _k_qp*(T_hessphi[i][qp](0,0) +
406  T_hessphi[i][qp](1,1) +
407  T_hessphi[i][qp](2,2))
408  )*fixed_deriv*JxW[qp];
409  (*KTw)(i,j) -=
410  tau_E*RE_t*
411  ( this->_rho*this->_Cp*u_phi[j][qp]*T_gradphi[i][qp](2)*fixed_deriv
412  )*JxW[qp];
413  }
414  }
415  }
416  }
417 
418  }
419 
420 #ifdef GRINS_USE_GRVY_TIMERS
421  this->_timer->EndTimer("HeatTransferAdjointStabilization::mass_residual");
422 #endif
423  return;
424  }
425 
426 } // namespace GRINS
427 
428 // Instantiate
429 INSTANTIATE_HEAT_TRANSFER_SUBCLASS(HeatTransferAdjointStabilization);
INSTANTIATE_HEAT_TRANSFER_SUBCLASS(HeatTransferAdjointStabilization)
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Time dependent part(s) of physics for element interiors.
GRINS namespace.
virtual void mass_residual(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part...

Generated on Mon Jun 22 2015 21:32:20 for GRINS-0.6.0 by  doxygen 1.8.9.1