MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
heat_conduction_elem_base.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 // MAST includes
25 #include "base/parameter.h"
28 #include "base/nonlinear_system.h"
29 #include "base/assembly_base.h"
30 #include "mesh/fe_base.h"
31 #include "mesh/geom_elem.h"
33 
34 
37  const MAST::GeomElem& elem,
39 MAST::ElementBase (sys, elem),
40 _property (p) {
41 
42 }
43 
44 
45 
47 
48 }
49 
50 
51 
52 
53 void
55  RealVectorX& f,
56  RealMatrixX& jac) {
57 
58  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(true, false));
59 
60  const std::vector<Real>& JxW = fe->get_JxW();
61  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
62  const unsigned int
63  n_phi = fe->n_shape_functions(),
64  dim = _elem.dim();
65 
67  material_mat = RealMatrixX::Zero(dim, dim),
68  dmaterial_mat = RealMatrixX::Zero(dim, dim), // for calculation of Jac when k is temp. dep.
69  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi);
71  vec1 = RealVectorX::Zero(1),
72  vec2_n2 = RealVectorX::Zero(n_phi),
73  flux = RealVectorX::Zero(dim);
74 
75  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > conductance =
77 
78  std::vector<MAST::FEMOperatorMatrix> dBmat(dim);
79  MAST::FEMOperatorMatrix Bmat; // for calculation of Jac when k is temp. dep.
80 
81 
82  for (unsigned int qp=0; qp<JxW.size(); qp++) {
83 
84  // initialize the Bmat operator for this term
85  _initialize_mass_fem_operator(qp, *fe, Bmat);
86  Bmat.right_multiply(vec1, _sol);
87 
89  dynamic_cast<MAST::MeshFieldFunction*>
90  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
91 
92  (*conductance)(xyz[qp], _time, material_mat);
93 
94  _initialize_fem_gradient_operator(qp, dim, *fe, dBmat);
95 
96  // calculate the flux for each dimension and add its weighted
97  // component to the residual
98  flux.setZero();
99  for (unsigned int j=0; j<dim; j++) {
100  dBmat[j].right_multiply(vec1, _sol); // dT_dxj
101 
102  for (unsigned int i=0; i<dim; i++)
103  flux(i) += vec1(0) * material_mat(i,j); // q_i = k_ij dT_dxj
104  }
105 
106  // now add to the residual vector
107  for (unsigned int i=0; i<dim; i++) {
108  vec1(0) = flux(i);
109  dBmat[i].vector_mult_transpose(vec2_n2, vec1);
110  f += JxW[qp] * vec2_n2;
111  }
112 
113 
114  if (request_jacobian) {
115 
116  // Jacobian contribution from int_omega dB_dxi^T k_ij dB_dxj
117  for (unsigned int i=0; i<dim; i++)
118  for (unsigned int j=0; j<dim; j++) {
119 
120  dBmat[i].right_multiply_transpose(mat_n2n2, dBmat[j]);
121  jac += JxW[qp] * material_mat(i,j) * mat_n2n2;
122  }
123 
124  // Jacobian contribution from int_omega dB_dxi dT_dxj dk_ij/dT B
125  if (_active_sol_function) {
126  // get derivative of the conductance matrix wrt temperature
127  conductance->derivative(*_active_sol_function,
128  xyz[qp],
129  _time, dmaterial_mat);
130 
131  for (unsigned int j=0; j<dim; j++) {
132  dBmat[j].right_multiply(vec1, _sol); // dT_dxj
133 
134  for (unsigned int i=0; i<dim; i++)
135  if (dmaterial_mat(i,j) != 0.) { // no need to process for zero terms
136  // dB_dxi^T B
137  dBmat[i].right_multiply_transpose(mat_n2n2, Bmat);
138  // dB_dxi^T (dT_dxj dk_ij/dT) B
139  jac += JxW[qp] * vec1(0) * dmaterial_mat(i,j) * mat_n2n2;
140  }
141  }
142  }
143  }
144  }
145 
147  dynamic_cast<MAST::MeshFieldFunction*>
148  (_active_sol_function)->clear_element_quadrature_point_solution();
149 }
150 
151 
152 
153 
154 
155 void
157  RealVectorX& f,
158  RealMatrixX& jac_xdot,
159  RealMatrixX& jac) {
161 
162  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
163 
164  const std::vector<Real>& JxW = fe->get_JxW();
165  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
166 
167  const unsigned int
168  n_phi = fe->n_shape_functions(),
169  dim = _elem.dim();
170 
172  material_mat = RealMatrixX::Zero(dim, dim),
173  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi);
175  vec1 = RealVectorX::Zero(1),
176  vec2_n2 = RealVectorX::Zero(n_phi),
177  local_f = RealVectorX::Zero(n_phi);
178 
179  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > capacitance =
181 
182  for (unsigned int qp=0; qp<JxW.size(); qp++) {
183 
184  _initialize_mass_fem_operator(qp, *fe, Bmat);
185  Bmat.right_multiply(vec1, _sol); // B * T
186 
188  dynamic_cast<MAST::MeshFieldFunction*>
189  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
190 
191  (*capacitance)(xyz[qp], _time, material_mat);
192 
193  Bmat.right_multiply(vec1, _vel); // B * T_dot
194  Bmat.vector_mult_transpose(vec2_n2, vec1); // B^T * B * T_dot
195 
196  local_f += JxW[qp] * material_mat(0,0) * vec2_n2; // (rho*cp)*JxW B^T B T_dot
197 
198  if (request_jacobian || _property.if_diagonal_mass_matrix()) {
199 
200  Bmat.right_multiply_transpose(mat_n2n2, Bmat); // B^T B
201  jac_xdot += JxW[qp] * material_mat(0,0) * mat_n2n2; // B^T B * JxW (rho*cp)
202 
203  // Jacobian contribution from int_omega B T d(rho*cp)/dT B
204  if (_active_sol_function) {
205  // get derivative of the conductance matrix wrt temperature
206  capacitance->derivative(*_active_sol_function,
207  xyz[qp],
208  _time, material_mat);
209 
210  if (material_mat(0,0) != 0.) { // no need to process for zero terms
211 
212  // B^T (T d(rho cp)/dT) B
213  jac += JxW[qp] * vec1(0) * material_mat(0,0) * mat_n2n2;
214  }
215  }
216  }
217  }
218 
219  // diagonalize the matrix and compute the residual based on that.
221 
222  for (unsigned int i=0; i<jac_xdot.rows(); i++) {
223 
224  Real a = jac_xdot.row(i).sum();
225  jac_xdot.row(i).setZero();
226  jac_xdot(i,i) = a;
227  }
228 
229  f += jac_xdot * _vel;
230 
231  // if the jacobian was not requested, then zero the matrix.
232  if (!request_jacobian) {
233  jac_xdot.setZero();
234  jac.setZero();
235  }
236  }
237  else
238  f += local_f;
239 
241  dynamic_cast<MAST::MeshFieldFunction*>
242  (_active_sol_function)->clear_element_quadrature_point_solution();
243 }
244 
245 
246 
247 
248 void
250 side_external_residual (bool request_jacobian,
251  RealVectorX& f,
252  RealMatrixX& jac,
253  std::multimap<libMesh::boundary_id_type, MAST::BoundaryConditionBase*>& bc) {
254 
255  std::map<unsigned int, std::vector<MAST::BoundaryConditionBase*>> loads;
257 
258  std::map<unsigned int, std::vector<MAST::BoundaryConditionBase*>>::const_iterator
259  it = loads.begin(),
260  end = loads.end();
261 
262  for ( ; it != end; it++) {
263 
264  std::vector<MAST::BoundaryConditionBase*>::const_iterator
265  bc_it = it->second.begin(),
266  bc_end = it->second.end();
267 
268  for ( ; bc_it != bc_end; bc_it++) {
269 
270  // apply all the types of loading
271  switch ((*bc_it)->type()) {
272  case MAST::HEAT_FLUX:
273  surface_flux_residual(request_jacobian,
274  f, jac,
275  it->first,
276  **bc_it);
277  break;
278 
280  surface_convection_residual(request_jacobian,
281  f, jac,
282  it->first,
283  **bc_it);
284  break;
285 
287  surface_radiation_residual(request_jacobian,
288  f, jac,
289  it->first,
290  **bc_it);
291  break;
292 
293  case MAST::DIRICHLET:
294  // nothing to be done here
295  break;
296 
297  default:
298  // not implemented yet
299  libmesh_error();
300  break;
301  }
302  }
303  }
304 }
305 
306 
307 
308 
309 
310 void
312 volume_external_residual (bool request_jacobian,
313  RealVectorX& f,
314  RealMatrixX& jac,
315  std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*>& bc) {
316 
317  typedef std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*> maptype;
318 
319  // iterate over the boundary ids given in the provided force map
320  std::pair<maptype::const_iterator, maptype::const_iterator> it;
321 
322  // for each boundary id, check if any of the sides on the element
323  // has the associated boundary
324 
325  libMesh::subdomain_id_type sid = _elem.get_reference_elem().subdomain_id();
326  // find the loads on this boundary and evaluate the f and jac
327  it =bc.equal_range(sid);
328 
329  for ( ; it.first != it.second; it.first++) {
330  // apply all the types of loading
331  switch (it.first->second->type()) {
332 
333  case MAST::HEAT_FLUX:
334  surface_flux_residual(request_jacobian,
335  f, jac,
336  *it.first->second);
337  break;
339  surface_convection_residual(request_jacobian,
340  f, jac,
341  *it.first->second);
342  break;
343 
345  surface_radiation_residual(request_jacobian,
346  f, jac,
347  *it.first->second);
348  break;
349 
350  case MAST::HEAT_SOURCE:
351  volume_heat_source_residual(request_jacobian,
352  f, jac,
353  *it.first->second);
354  break;
355 
356  default:
357  // not implemented yet
358  libmesh_error();
359  break;
360  }
361  }
362 
363 }
364 
365 
366 
367 void
370  RealVectorX& f,
371  std::multimap<libMesh::boundary_id_type, MAST::BoundaryConditionBase*>& bc) {
372 
373  std::map<unsigned int, std::vector<MAST::BoundaryConditionBase*>> loads;
375 
376  std::map<unsigned int, std::vector<MAST::BoundaryConditionBase*>>::const_iterator
377  it = loads.begin(),
378  end = loads.end();
379 
380  for ( ; it != end; it++) {
381 
382  std::vector<MAST::BoundaryConditionBase*>::const_iterator
383  bc_it = it->second.begin(),
384  bc_end = it->second.end();
385 
386  for ( ; bc_it != bc_end; bc_it++) {
387 
388  // apply all the types of loading
389  switch ((*bc_it)->type()) {
390  case MAST::HEAT_FLUX:
392  f,
393  it->first,
394  **bc_it);
395  break;
396 
399  f,
400  it->first,
401  **bc_it);
402  break;
403 
406  f,
407  it->first,
408  **bc_it);
409  break;
410 
411  case MAST::DIRICHLET:
412  // nothing to be done here
413  break;
414 
415  default:
416  // not implemented yet
417  libmesh_error();
418  break;
419  }
420  }
421  }
422 }
423 
424 
425 
426 
427 void
430  RealVectorX& f,
431  std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*>& bc) {
432 
433  typedef std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*> maptype;
434 
435  // iterate over the boundary ids given in the provided force map
436  std::pair<maptype::const_iterator, maptype::const_iterator> it;
437 
438  // for each boundary id, check if any of the sides on the element
439  // has the associated boundary
440 
441  libMesh::subdomain_id_type sid = _elem.get_reference_elem().subdomain_id();
442  // find the loads on this boundary and evaluate the f and jac
443  it =bc.equal_range(sid);
444 
445  for ( ; it.first != it.second; it.first++) {
446  // apply all the types of loading
447  switch (it.first->second->type()) {
448 
449  case MAST::HEAT_FLUX:
451  f,
452  *it.first->second);
453  break;
454 
457  f,
458  *it.first->second);
459  break;
460 
463  f,
464  *it.first->second);
465  break;
466 
467  case MAST::HEAT_SOURCE:
469  f,
470  *it.first->second);
471  break;
472 
473  default:
474  // not implemented yet
475  libmesh_error();
476  break;
477  }
478  }
479 
480 }
481 
482 
483 
484 void
487  RealVectorX& f,
488  const unsigned int s,
490  std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*>& bc) {
491 
492  typedef std::multimap<libMesh::subdomain_id_type, MAST::BoundaryConditionBase*> maptype;
493 
494  // iterate over the boundary ids given in the provided force map
495  std::pair<maptype::const_iterator, maptype::const_iterator> it;
496 
497  // for each boundary id, check if any of the sides on the element
498  // has the associated boundary
499 
500  libMesh::subdomain_id_type sid = _elem.get_reference_elem().subdomain_id();
501  // find the loads on this boundary and evaluate the f and jac
502  it =bc.equal_range(sid);
503 
504  for ( ; it.first != it.second; it.first++) {
505  // apply all the types of loading
506  switch (it.first->second->type()) {
507 
508  case MAST::HEAT_FLUX:
510  f,
511  s,
512  vel_f,
513  *it.first->second);
514  break;
515 
518  f,
519  s,
520  vel_f,
521  *it.first->second);
522  break;
523 
526  f,
527  s,
528  vel_f,
529  *it.first->second);
530  break;
531 
532  case MAST::HEAT_SOURCE:
534  f,
535  s,
536  vel_f,
537  *it.first->second);
538  break;
539 
540  default:
541  // not implemented yet
542  libmesh_error();
543  break;
544  }
545  }
546 
547 }
548 
549 
550 
551 
552 void
555  RealVectorX& f) {
556 
557  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(true, false));
558 
559  const std::vector<Real>& JxW = fe->get_JxW();
560  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
561  const unsigned int
562  n_phi = fe->n_shape_functions(),
563  dim = _elem.dim();
564 
566  material_mat = RealMatrixX::Zero(dim, dim),
567  dmaterial_mat = RealMatrixX::Zero(dim, dim), // for calculation of Jac when k is temp. dep.
568  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi);
570  vec1 = RealVectorX::Zero(1),
571  vec2_n2 = RealVectorX::Zero(n_phi),
572  flux = RealVectorX::Zero(dim);
573 
574  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > conductance =
576 
577  std::vector<MAST::FEMOperatorMatrix> dBmat(dim);
578  MAST::FEMOperatorMatrix Bmat; // for calculation of Jac when k is temp. dep.
579 
580 
581  for (unsigned int qp=0; qp<JxW.size(); qp++) {
582 
583  // initialize the Bmat operator for this term
584  _initialize_mass_fem_operator(qp, *fe, Bmat);
585  Bmat.right_multiply(vec1, _sol);
586 
588  dynamic_cast<MAST::MeshFieldFunction*>
589  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
590 
591  conductance->derivative(p, xyz[qp], _time, material_mat);
592 
593  _initialize_fem_gradient_operator(qp, dim, *fe, dBmat);
594 
595  // calculate the flux for each dimension and add its weighted
596  // component to the residual
597  flux.setZero();
598  for (unsigned int j=0; j<dim; j++) {
599  dBmat[j].right_multiply(vec1, _sol); // dT_dxj
600 
601  for (unsigned int i=0; i<dim; i++)
602  flux(i) += vec1(0) * material_mat(i,j); // q_i = k_ij dT_dxj
603  }
604 
605  // now add to the residual vector
606  for (unsigned int i=0; i<dim; i++) {
607  vec1(0) = flux(i);
608  dBmat[i].vector_mult_transpose(vec2_n2, vec1);
609  f += JxW[qp] * vec2_n2;
610  }
611  }
612 
614  dynamic_cast<MAST::MeshFieldFunction*>
615  (_active_sol_function)->clear_element_quadrature_point_solution();
616 
617 }
618 
619 
620 void
623  RealVectorX& f,
624  const unsigned int s,
625  const MAST::FieldFunction<RealVectorX>& vel_f) {
626 
627  // prepare the side finite element
628  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, true, false));
629 
630  std::vector<Real> JxW_Vn = fe->get_JxW();
631  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
632  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
633 
634  const unsigned int
635  n_phi = fe->n_shape_functions(),
636  dim = _elem.dim();
637 
639  material_mat = RealMatrixX::Zero(dim, dim),
640  dmaterial_mat = RealMatrixX::Zero(dim, dim), // for calculation of Jac when k is temp. dep.
641  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi);
643  vec1 = RealVectorX::Zero(1),
644  vec2_n2 = RealVectorX::Zero(n_phi),
645  flux = RealVectorX::Zero(dim),
646  vel = RealVectorX::Zero(dim);
647 
648  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > conductance =
650 
651  std::vector<MAST::FEMOperatorMatrix> dBmat(dim);
652  MAST::FEMOperatorMatrix Bmat; // for calculation of Jac when k is temp. dep.
653 
654  Real
655  vn = 0.;
656 
657  // modify the JxW_Vn by multiplying the normal velocity to it
658  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
659 
660  vel_f.derivative(p, xyz[qp], _time, vel);
661  vn = 0.;
662  for (unsigned int i=0; i<dim; i++)
663  vn += vel(i)*face_normals[qp](i);
664  JxW_Vn[qp] *= vn;
665  }
666 
667 
668  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
669 
670  // initialize the Bmat operator for this term
671  _initialize_mass_fem_operator(qp, *fe, Bmat);
672  Bmat.right_multiply(vec1, _sol);
673 
675  dynamic_cast<MAST::MeshFieldFunction*>
676  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
677 
678  (*conductance)(xyz[qp], _time, material_mat);
679 
680  _initialize_fem_gradient_operator(qp, dim, *fe, dBmat);
681 
682  // calculate the flux for each dimension and add its weighted
683  // component to the residual
684  flux.setZero();
685  for (unsigned int j=0; j<dim; j++) {
686  dBmat[j].right_multiply(vec1, _sol); // dT_dxj
687 
688  for (unsigned int i=0; i<dim; i++)
689  flux(i) += vec1(0) * material_mat(i,j); // q_i = k_ij dT_dxj
690  }
691 
692  // now add to the residual vector
693  for (unsigned int i=0; i<dim; i++) {
694  vec1(0) = flux(i);
695  dBmat[i].vector_mult_transpose(vec2_n2, vec1);
696  f += JxW_Vn[qp] * vec2_n2;
697  }
698  }
699 
701  dynamic_cast<MAST::MeshFieldFunction*>
702  (_active_sol_function)->clear_element_quadrature_point_solution();
703 }
704 
705 
706 
707 void
710  RealVectorX& f) {
711 
713 
714  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
715 
716  const std::vector<Real>& JxW = fe->get_JxW();
717  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
718 
719  const unsigned int
720  n_phi = fe->n_shape_functions(),
721  dim = _elem.dim();
722 
724  material_mat = RealMatrixX::Zero(dim, dim),
725  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi),
726  local_jac_xdot = RealMatrixX::Zero(n_phi, n_phi);
727 
729  vec1 = RealVectorX::Zero(1),
730  vec2_n2 = RealVectorX::Zero(n_phi),
731  local_f = RealVectorX::Zero(n_phi);
732 
733  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > capacitance =
735 
736  for (unsigned int qp=0; qp<JxW.size(); qp++) {
737 
738  _initialize_mass_fem_operator(qp, *fe, Bmat);
739  Bmat.right_multiply(vec1, _sol); // B * T
740 
742  dynamic_cast<MAST::MeshFieldFunction*>
743  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
744 
745  capacitance->derivative(p, xyz[qp], _time, material_mat);
746 
747  Bmat.right_multiply(vec1, _vel); // B * T_dot
748  Bmat.vector_mult_transpose(vec2_n2, vec1); // B^T * B * T_dot
749 
750  local_f += JxW[qp] * material_mat(0,0) * vec2_n2; // (rho*cp)*JxW B^T B T_dot
751 
753 
754  Bmat.right_multiply_transpose(mat_n2n2, Bmat); // B^T B
755  local_jac_xdot += JxW[qp] * material_mat(0,0) * mat_n2n2; // B^T B * JxW (rho*cp)
756  }
757  }
758 
760 
761  for (unsigned int i=0; i<local_jac_xdot.rows(); i++) {
762 
763  Real a = local_jac_xdot.row(i).sum();
764  local_jac_xdot.row(i).setZero();
765  local_jac_xdot(i,i) = a;
766  }
767 
768  f += local_jac_xdot * _vel;
769  }
770  else
771  f += local_f;
772 
774  dynamic_cast<MAST::MeshFieldFunction*>
775  (_active_sol_function)->clear_element_quadrature_point_solution();
776 
777 }
778 
779 
780 
781 void
784  RealVectorX& f,
785  const unsigned int s,
786  const MAST::FieldFunction<RealVectorX>& vel_f) {
787 
788  // prepare the side finite element
789  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
790 
791  std::vector<Real> JxW_Vn = fe->get_JxW();
792  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
793  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
794 
796 
797  const unsigned int
798  n_phi = fe->n_shape_functions(),
799  dim = _elem.dim();
800 
802  material_mat = RealMatrixX::Zero(dim, dim),
803  mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi),
804  local_jac_xdot = RealMatrixX::Zero(n_phi, n_phi);
806  vec1 = RealVectorX::Zero(1),
807  vec2_n2 = RealVectorX::Zero(n_phi),
808  local_f = RealVectorX::Zero(n_phi),
809  vel = RealVectorX::Zero(dim);
810 
811  std::unique_ptr<MAST::FieldFunction<RealMatrixX> > capacitance =
813 
814  Real
815  vn = 0.;
816 
817  // modify the JxW_Vn by multiplying the normal velocity to it
818  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
819 
820  vel_f.derivative(p, xyz[qp], _time, vel);
821  vn = 0.;
822  for (unsigned int i=0; i<dim; i++)
823  vn += vel(i)*face_normals[qp](i);
824  JxW_Vn[qp] *= vn;
825  }
826 
827  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
828 
829  _initialize_mass_fem_operator(qp, *fe, Bmat);
830  Bmat.right_multiply(vec1, _sol); // B * T
831 
833  dynamic_cast<MAST::MeshFieldFunction*>
834  (_active_sol_function)->set_element_quadrature_point_solution(vec1);
835 
836  (*capacitance)(xyz[qp], _time, material_mat);
837 
838  Bmat.right_multiply(vec1, _vel); // B * T_dot
839  Bmat.vector_mult_transpose(vec2_n2, vec1); // B^T * B * T_dot
840 
841  local_f += JxW_Vn[qp] * material_mat(0,0) * vec2_n2; // (rho*cp)*JxW B^T B T_dot
842 
844 
845  Bmat.right_multiply_transpose(mat_n2n2, Bmat); // B^T B
846  local_jac_xdot += JxW_Vn[qp] * material_mat(0,0) * mat_n2n2; // B^T B * JxW (rho*cp)
847  }
848  }
849 
850  // diagonalize the matrix and compute the residual based on that.
852 
853  for (unsigned int i=0; i<local_jac_xdot.rows(); i++) {
854 
855  Real a = local_jac_xdot.row(i).sum();
856  local_jac_xdot.row(i).setZero();
857  local_jac_xdot(i,i) = a;
858  }
859 
860  f += local_jac_xdot * _vel;
861  }
862  else
863  f += local_f;
864 
865 
867  dynamic_cast<MAST::MeshFieldFunction*>
868  (_active_sol_function)->clear_element_quadrature_point_solution();
869 }
870 
871 
872 
873 
874 
875 void
877 surface_flux_residual(bool request_jacobian,
878  RealVectorX& f,
879  RealMatrixX& jac,
880  const unsigned int s,
882 
883  // prepare the side finite element
884  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
885 
886 
887  // get the function from this boundary condition
889  &func = bc.get<MAST::FieldFunction<Real> >("heat_flux"),
890  *section = _property.section(*this);
891 
892  const std::vector<Real> &JxW = fe->get_JxW();
893  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
894  const std::vector<std::vector<Real> >& phi = fe->get_phi();
895  const unsigned int n_phi = (unsigned int)phi.size();
896 
897  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
898  Real flux, th;
899 
900  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
901 
902  // now set the shape function values
903  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
904  phi_vec(i_nd) = phi[i_nd][qp];
905 
906  // get the value of flux = q_i . n_i
907  func(qpoint[qp], _time, flux);
908  if (section) (*section)(qpoint[qp], _time, th);
909  else th = 1.;
910 
911  f += JxW[qp] * phi_vec * flux * th;
912  }
913 }
914 
915 
916 
917 
918 
919 void
921 surface_flux_residual(bool request_jacobian,
922  RealVectorX& f,
923  RealMatrixX& jac,
925 
926  // get the function from this boundary condition
927  const MAST::FieldFunction<Real>& func =
928  bc.get<MAST::FieldFunction<Real> >("heat_flux");
929 
930  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
931 
932  const std::vector<Real> &JxW = fe->get_JxW();
933  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
934  const std::vector<std::vector<Real> >& phi = fe->get_phi();
935  const unsigned int n_phi = (unsigned int)phi.size();
936 
937  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
938  Real flux;
939 
940  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
941 
942  // now set the shape function values
943  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
944  phi_vec(i_nd) = phi[i_nd][qp];
945 
946  // get the value of flux = q_i . n_i
947  func(qpoint[qp], _time, flux);
948 
949  f += JxW[qp] * phi_vec * flux;
950  }
951 }
952 
953 
954 
955 
956 void
959  RealVectorX& f,
960  const unsigned int s,
962 
963  // prepare the side finite element
964  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
965 
966 
967  // get the function from this boundary condition
969  &func = bc.get<MAST::FieldFunction<Real> >("heat_flux"),
970  *section = _property.section(*this);
971 
972 
973  const std::vector<Real> &JxW = fe->get_JxW();
974  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
975  const std::vector<std::vector<Real> >& phi = fe->get_phi();
976  const unsigned int n_phi = (unsigned int)phi.size();
977 
978  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
979  Real flux, dflux, th, dth;
980 
981  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
982 
983  // now set the shape function values
984  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
985  phi_vec(i_nd) = phi[i_nd][qp];
986 
987  // get the value of flux = q_i . n_i
988  func(qpoint[qp], _time, flux);
989  func.derivative(p, qpoint[qp], _time, dflux);
990  if (section) {
991 
992  (*section)(qpoint[qp], _time, th);
993  section->derivative(p, qpoint[qp], _time, dth);
994  }
995  else {
996  th = 1.;
997  dth = 0.;
998  }
999 
1000  f += JxW[qp] * phi_vec * (flux*dth + dflux*th);
1001  }
1002 }
1003 
1004 
1005 
1006 
1007 void
1010  RealVectorX& f,
1012 
1013  // get the function from this boundary condition
1014  const MAST::FieldFunction<Real>& func =
1015  bc.get<MAST::FieldFunction<Real> >("heat_flux");
1016 
1017  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1018 
1019  const std::vector<Real> &JxW = fe->get_JxW();
1020  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1021  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1022  const unsigned int n_phi = (unsigned int)phi.size();
1023 
1024  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1025  Real flux;
1026 
1027  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1028 
1029  // now set the shape function values
1030  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1031  phi_vec(i_nd) = phi[i_nd][qp];
1032 
1033  // get the value of flux = q_i . n_i
1034  func.derivative(p, qpoint[qp], _time, flux);
1035 
1036  f += JxW[qp] * phi_vec * flux;
1037  }
1038 }
1039 
1040 
1041 
1042 void
1045  RealVectorX& f,
1046  const unsigned int s,
1047  const MAST::FieldFunction<RealVectorX>& vel_f,
1049 
1050 
1051  // prepare the side finite element
1052  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1053 
1054  std::vector<Real> JxW_Vn = fe->get_JxW();
1055  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
1056  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
1057  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1058  const unsigned int
1059  n_phi = (unsigned int)phi.size(),
1060  dim = _elem.dim();
1061 
1062  RealVectorX
1063  phi_vec = RealVectorX::Zero(n_phi),
1064  vel = RealVectorX::Zero(dim);
1065  Real flux;
1066 
1067  Real
1068  vn = 0.;
1069 
1070  // modify the JxW_Vn by multiplying the normal velocity to it
1071  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
1072 
1073  vel_f.derivative(p, xyz[qp], _time, vel);
1074  vn = 0.;
1075  for (unsigned int i=0; i<dim; i++)
1076  vn += vel(i)*face_normals[qp](i);
1077  JxW_Vn[qp] *= vn;
1078  }
1079 
1080  // get the function from this boundary condition
1081  const MAST::FieldFunction<Real>& func =
1082  bc.get<MAST::FieldFunction<Real> >("heat_flux");
1083 
1084 
1085  for (unsigned int qp=0; qp<xyz.size(); qp++) {
1086 
1087  // now set the shape function values
1088  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1089  phi_vec(i_nd) = phi[i_nd][qp];
1090 
1091  // get the value of flux = q_i . n_i
1092  func(xyz[qp], _time, flux);
1093 
1094  f += JxW_Vn[qp] * phi_vec * flux;
1095  }
1096 }
1097 
1098 
1099 void
1101 surface_convection_residual(bool request_jacobian,
1102  RealVectorX& f,
1103  RealMatrixX& jac,
1104  const unsigned int s,
1106 
1107  // prepare the side finite element
1108  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1109 
1110  // get the function from this boundary condition
1112  &coeff = bc.get<MAST::FieldFunction<Real> >("convection_coeff"),
1113  &T_amb = bc.get<MAST::FieldFunction<Real> >("ambient_temperature"),
1114  *section = _property.section(*this);
1115 
1116  const std::vector<Real> &JxW = fe->get_JxW();
1117  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1118  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1119  const unsigned int n_phi = (unsigned int)phi.size();
1120 
1121 
1122  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1123  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1124  Real temp, amb_temp, h_coeff, th;
1126 
1127 
1128  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1129 
1130  // now set the shape function values
1131  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1132  phi_vec(i_nd) = phi[i_nd][qp];
1133 
1134  // value of flux
1135  coeff(qpoint[qp], _time, h_coeff);
1136  T_amb(qpoint[qp], _time, amb_temp);
1137  temp = phi_vec.dot(_sol);
1138  if (section) (*section)(qpoint[qp], _time, th);
1139  else th = 1.;
1140 
1141  // normal flux is given as:
1142  // qi_ni = h_coeff * (T - T_amb)
1143  //
1144  f += JxW[qp] * phi_vec * th* h_coeff * (temp - amb_temp);
1145 
1146  if (request_jacobian) {
1147 
1148  Bmat.reinit(1, phi_vec);
1149  Bmat.right_multiply_transpose(mat, Bmat);
1150  jac += JxW[qp] * mat * th * h_coeff;
1151  }
1152  }
1153 
1154 }
1155 
1156 
1157 
1158 
1159 
1160 void
1162 surface_convection_residual(bool request_jacobian,
1163  RealVectorX& f,
1164  RealMatrixX& jac,
1166 
1167  // get the function from this boundary condition
1169  &coeff = bc.get<MAST::FieldFunction<Real> >("convection_coeff"),
1170  &T_amb = bc.get<MAST::FieldFunction<Real> >("ambient_temperature");
1171 
1172  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1173 
1174  const std::vector<Real> &JxW = fe->get_JxW();
1175  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1176  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1177  const unsigned int n_phi = (unsigned int)phi.size();
1178 
1179 
1180  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1181  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1182  Real temp, amb_temp, h_coeff;
1184 
1185 
1186  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1187 
1188  // now set the shape function values
1189  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1190  phi_vec(i_nd) = phi[i_nd][qp];
1191 
1192  // value of flux
1193  coeff(qpoint[qp], _time, h_coeff);
1194  T_amb(qpoint[qp], _time, amb_temp);
1195  temp = phi_vec.dot(_sol);
1196 
1197  // normal flux is given as:
1198  // qi_ni = h_coeff * (T - T_amb)
1199  //
1200  f += JxW[qp] * phi_vec * h_coeff * (temp - amb_temp);
1201 
1202  if (request_jacobian) {
1203 
1204  Bmat.reinit(1, phi_vec);
1205  Bmat.right_multiply_transpose(mat, Bmat);
1206  jac += JxW[qp] * mat * h_coeff;
1207  }
1208  }
1209 
1210 }
1211 
1212 
1213 
1214 
1215 
1216 void
1219  RealVectorX& f,
1220  const unsigned int s,
1222 
1223  // prepare the side finite element
1224  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1225 
1226  // get the function from this boundary condition
1228  &coeff = bc.get<MAST::FieldFunction<Real> >("convection_coeff"),
1229  &T_amb = bc.get<MAST::FieldFunction<Real> >("ambient_temperature"),
1230  *section = _property.section(*this);
1231 
1232  const std::vector<Real> &JxW = fe->get_JxW();
1233  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1234  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1235  const unsigned int n_phi = (unsigned int)phi.size();
1236 
1237 
1238  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1239  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1240  Real
1241  temp, amb_temp, h_coeff, th,
1242  damb_temp, dh_coeff, dth;
1244 
1245 
1246  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1247 
1248  // now set the shape function values
1249  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1250  phi_vec(i_nd) = phi[i_nd][qp];
1251 
1252  // value of flux
1253  coeff(qpoint[qp], _time, h_coeff);
1254  T_amb(qpoint[qp], _time, amb_temp);
1255  coeff.derivative(p, qpoint[qp], _time, dh_coeff);
1256  T_amb.derivative(p, qpoint[qp], _time, damb_temp);
1257  if (section) {
1258 
1259  (*section)(qpoint[qp], _time, th);
1260  section->derivative(p, qpoint[qp], _time, dth);
1261  }
1262  else {
1263  th = 1.;
1264  dth = 0.;
1265  }
1266  temp = phi_vec.dot(_sol);
1267 
1268  // normal flux is given as:
1269  // qi_ni = h_coeff * (T - T_amb)
1270  //
1271  f += JxW[qp] * phi_vec * (th * dh_coeff * (temp - amb_temp) +
1272  th * h_coeff * (-damb_temp) +
1273  dth* h_coeff * (temp - amb_temp));
1274  }
1275 }
1276 
1277 
1278 
1279 
1280 void
1283  RealVectorX& f,
1285 
1286  // get the function from this boundary condition
1288  &coeff = bc.get<MAST::FieldFunction<Real> >("convection_coeff"),
1289  &T_amb = bc.get<MAST::FieldFunction<Real> >("ambient_temperature");
1290 
1291  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1292 
1293  const std::vector<Real> &JxW = fe->get_JxW();
1294  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1295  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1296  const unsigned int n_phi = (unsigned int)phi.size();
1297 
1298 
1299  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1300  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1301  Real
1302  temp, amb_temp, h_coeff,
1303  damb_temp, dh_coeff;
1305 
1306 
1307  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1308 
1309  // now set the shape function values
1310  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1311  phi_vec(i_nd) = phi[i_nd][qp];
1312 
1313  // value of flux
1314  coeff(qpoint[qp], _time, h_coeff);
1315  T_amb(qpoint[qp], _time, amb_temp);
1316  coeff.derivative(p, qpoint[qp], _time, dh_coeff);
1317  T_amb.derivative(p, qpoint[qp], _time, damb_temp);
1318  temp = phi_vec.dot(_sol);
1319 
1320  // normal flux is given as:
1321  // qi_ni = h_coeff * (T - T_amb)
1322  //
1323  f += JxW[qp] * phi_vec * (dh_coeff * (temp - amb_temp)+
1324  h_coeff * (-damb_temp));
1325  }
1326 
1327 }
1328 
1329 
1330 
1331 void
1334  RealVectorX& f,
1335  const unsigned int s,
1336  const MAST::FieldFunction<RealVectorX>& vel_f,
1338 
1339  // prepare the side finite element
1340  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1341 
1342  std::vector<Real> JxW_Vn = fe->get_JxW();
1343  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
1344  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
1345  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1346 
1347  // get the function from this boundary condition
1349  &coeff = bc.get<MAST::FieldFunction<Real> >("convection_coeff"),
1350  &T_amb = bc.get<MAST::FieldFunction<Real> >("ambient_temperature");
1351 
1352  const unsigned int
1353  n_phi = (unsigned int)phi.size(),
1354  dim = _elem.dim();
1355 
1356 
1357  RealVectorX
1358  phi_vec = RealVectorX::Zero(n_phi),
1359  vel = RealVectorX::Zero(dim);
1360  RealMatrixX
1361  mat = RealMatrixX::Zero(n_phi, n_phi);
1362 
1363  Real temp, amb_temp, h_coeff;
1365 
1366  Real
1367  vn = 0.;
1368 
1369 
1370  // modify the JxW_Vn by multiplying the normal velocity to it
1371  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
1372 
1373  vel_f.derivative(p, xyz[qp], _time, vel);
1374  vn = 0.;
1375  for (unsigned int i=0; i<dim; i++)
1376  vn += vel(i)*face_normals[qp](i);
1377  JxW_Vn[qp] *= vn;
1378  }
1379 
1380  for (unsigned int qp=0; qp<xyz.size(); qp++) {
1381 
1382  // now set the shape function values
1383  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1384  phi_vec(i_nd) = phi[i_nd][qp];
1385 
1386  // value of flux
1387  coeff(xyz[qp], _time, h_coeff);
1388  T_amb(xyz[qp], _time, amb_temp);
1389  temp = phi_vec.dot(_sol);
1390 
1391  // normal flux is given as:
1392  // qi_ni = h_coeff * (T - T_amb)
1393  //
1394  f += JxW_Vn[qp] * phi_vec * h_coeff * (temp - amb_temp);
1395  }
1396 
1397 }
1398 
1399 
1400 
1401 
1402 void
1404 surface_radiation_residual(bool request_jacobian,
1405  RealVectorX& f,
1406  RealMatrixX& jac,
1407  const unsigned int s,
1409 
1410  // prepare the side finite element
1411  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1412 
1413  // get the function from this boundary condition
1415  &emissivity = bc.get<MAST::FieldFunction<Real> >("emissivity"),
1416  *section = _property.section(*this);
1417 
1418  const MAST::Parameter
1419  &T_amb = bc.get<MAST::Parameter>("ambient_temperature"),
1420  &T_ref_zero = bc.get<MAST::Parameter>("reference_zero_temperature"),
1421  &sb_const = bc.get<MAST::Parameter>("stefan_bolzmann_constant");
1422 
1423 
1424  const std::vector<Real> &JxW = fe->get_JxW();
1425  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1426  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1427  const unsigned int n_phi = (unsigned int)phi.size();
1428 
1429  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1430  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1431  const Real
1432  sbc = sb_const(),
1433  amb_temp = T_amb(),
1434  zero_ref = T_ref_zero();
1435  Real temp, emiss, th;
1437 
1438  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1439 
1440  // now set the shape function values
1441  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1442  phi_vec(i_nd) = phi[i_nd][qp];
1443 
1444  // value of flux
1445  emissivity(qpoint[qp], _time, emiss);
1446  temp = phi_vec.dot(_sol);
1447  if (section) (*section)(qpoint[qp], _time, th);
1448  else th = 1.;
1449 
1450  f += JxW[qp] * phi_vec * sbc * emiss * th *
1451  (pow(temp+zero_ref, 4.) - pow(amb_temp+zero_ref, 4.));
1452 
1453  if (request_jacobian) {
1454 
1455  Bmat.reinit(1, phi_vec);
1456  Bmat.right_multiply_transpose(mat, Bmat);
1457  jac += JxW[qp] * mat * sbc * emiss * th * 4. * pow(temp+zero_ref, 3.);
1458  }
1459  }
1460 }
1461 
1462 
1463 
1464 
1465 void
1467 surface_radiation_residual(bool request_jacobian,
1468  RealVectorX& f,
1469  RealMatrixX& jac,
1471 
1472  // get the function from this boundary condition
1474  &emissivity = bc.get<MAST::FieldFunction<Real> >("emissivity");
1475 
1476  const MAST::Parameter
1477  &T_amb = bc.get<MAST::Parameter>("ambient_temperature"),
1478  &T_ref_zero = bc.get<MAST::Parameter>("reference_zero_temperature"),
1479  &sb_const = bc.get<MAST::Parameter>("stefan_bolzmann_constant");
1480 
1481  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1482 
1483  const std::vector<Real> &JxW = fe->get_JxW();
1484  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1485  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1486  const unsigned int n_phi = (unsigned int)phi.size();
1487 
1488  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1489  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1490  const Real
1491  sbc = sb_const(),
1492  amb_temp = T_amb(),
1493  zero_ref = T_ref_zero();
1494  Real temp, emiss;
1496 
1497  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1498 
1499  // now set the shape function values
1500  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1501  phi_vec(i_nd) = phi[i_nd][qp];
1502 
1503  // value of flux
1504  emissivity(qpoint[qp], _time, emiss);
1505  temp = phi_vec.dot(_sol);
1506 
1507  f += JxW[qp] * phi_vec * sbc * emiss *
1508  (pow(temp+zero_ref, 4.) - pow(amb_temp+zero_ref, 4.));
1509 
1510  if (request_jacobian) {
1511 
1512  Bmat.reinit(1, phi_vec);
1513  Bmat.right_multiply_transpose(mat, Bmat);
1514  jac += JxW[qp] * mat * sbc * emiss * 4. * pow(temp+zero_ref, 3.);
1515  }
1516  }
1517 }
1518 
1519 
1520 
1521 
1522 
1523 void
1526  RealVectorX& f,
1527  const unsigned int s,
1529 
1530 
1531  // prepare the side finite element
1532  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1533 
1534  // get the function from this boundary condition
1536  &emissivity = bc.get<MAST::FieldFunction<Real> >("emissivity"),
1537  *section = _property.section(*this);
1538 
1539  const MAST::Parameter
1540  &T_amb = bc.get<MAST::Parameter>("ambient_temperature"),
1541  &T_ref_zero = bc.get<MAST::Parameter>("reference_zero_temperature"),
1542  &sb_const = bc.get<MAST::Parameter>("stefan_bolzmann_constant");
1543 
1544 
1545  const std::vector<Real> &JxW = fe->get_JxW();
1546  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1547  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1548  const unsigned int n_phi = (unsigned int)phi.size();
1549 
1550  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1551  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1552  const Real
1553  sbc = sb_const(),
1554  amb_temp = T_amb(),
1555  zero_ref = T_ref_zero();
1556  Real temp, emiss, demiss, th, dth;
1558 
1559  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1560 
1561  // now set the shape function values
1562  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1563  phi_vec(i_nd) = phi[i_nd][qp];
1564 
1565  // value of flux
1566  emissivity(qpoint[qp], _time, emiss);
1567  emissivity.derivative(p, qpoint[qp], _time, demiss);
1568  temp = phi_vec.dot(_sol);
1569  if (section) {
1570 
1571  (*section)(qpoint[qp], _time, th);
1572  section->derivative(p, qpoint[qp], _time, dth);
1573  }
1574  else {
1575  th = 1.;
1576  dth = 0.;
1577  }
1578 
1579  f += JxW[qp] * phi_vec * sbc * (demiss * th + emiss * dth) *
1580  (pow(temp+zero_ref, 4.) - pow(amb_temp+zero_ref, 4.));
1581  }
1582 }
1583 
1584 
1585 
1586 
1587 void
1590  RealVectorX& f,
1592 
1593  // get the function from this boundary condition
1595  &emissivity = bc.get<MAST::FieldFunction<Real> >("emissivity");
1596 
1597  const MAST::Parameter
1598  &T_amb = bc.get<MAST::Parameter>("ambient_temperature"),
1599  &T_ref_zero = bc.get<MAST::Parameter>("reference_zero_temperature"),
1600  &sb_const = bc.get<MAST::Parameter>("stefan_bolzmann_constant");
1601 
1602  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1603 
1604  const std::vector<Real> &JxW = fe->get_JxW();
1605  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1606  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1607  const unsigned int n_phi = (unsigned int)phi.size();
1608 
1609  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1610  RealMatrixX mat = RealMatrixX::Zero(n_phi, n_phi);
1611  const Real
1612  sbc = sb_const(),
1613  amb_temp = T_amb(),
1614  zero_ref = T_ref_zero();
1615  Real temp, demiss;
1617 
1618  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1619 
1620  // now set the shape function values
1621  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1622  phi_vec(i_nd) = phi[i_nd][qp];
1623 
1624  // value of flux
1625  emissivity.derivative(p, qpoint[qp], _time, demiss);
1626  temp = phi_vec.dot(_sol);
1627 
1628  f += JxW[qp] * phi_vec * sbc * demiss *
1629  (pow(temp+zero_ref, 4.) - pow(amb_temp+zero_ref, 4.));
1630  }
1631 }
1632 
1633 
1634 void
1637  RealVectorX& f,
1638  const unsigned int s,
1639  const MAST::FieldFunction<RealVectorX>& vel_f,
1641 
1642  // prepare the side finite element
1643  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1644 
1645  std::vector<Real> JxW_Vn = fe->get_JxW();
1646  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
1647  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
1648  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1649 
1650  // get the function from this boundary condition
1652  &emissivity = bc.get<MAST::FieldFunction<Real> >("emissivity");
1653 
1654  const MAST::Parameter
1655  &T_amb = bc.get<MAST::Parameter>("ambient_temperature"),
1656  &T_ref_zero = bc.get<MAST::Parameter>("reference_zero_temperature"),
1657  &sb_const = bc.get<MAST::Parameter>("stefan_bolzmann_constant");
1658 
1659  const unsigned int
1660  n_phi = (unsigned int)phi.size(),
1661  dim = _elem.dim();
1662 
1663  RealVectorX
1664  phi_vec = RealVectorX::Zero(n_phi),
1665  vel = RealVectorX::Zero(dim);
1666  RealMatrixX
1667  mat = RealMatrixX::Zero(n_phi, n_phi);
1668 
1669  const Real
1670  sbc = sb_const(),
1671  amb_temp = T_amb(),
1672  zero_ref = T_ref_zero();
1673 
1674  Real
1675  temp = 0.,
1676  emiss = 0.,
1677  vn = 0.;
1678 
1680 
1681 
1682  // modify the JxW_Vn by multiplying the normal velocity to it
1683  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
1684 
1685  vel_f.derivative(p, xyz[qp], _time, vel);
1686  vn = 0.;
1687  for (unsigned int i=0; i<dim; i++)
1688  vn += vel(i)*face_normals[qp](i);
1689  JxW_Vn[qp] *= vn;
1690  }
1691 
1692  for (unsigned int qp=0; qp<xyz.size(); qp++) {
1693 
1694  // now set the shape function values
1695  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1696  phi_vec(i_nd) = phi[i_nd][qp];
1697 
1698  // value of flux
1699  emissivity(xyz[qp], _time, emiss);
1700  temp = phi_vec.dot(_sol);
1701 
1702  f += JxW_Vn[qp] * phi_vec * sbc * emiss *
1703  (pow(temp+zero_ref, 4.) - pow(amb_temp+zero_ref, 4.));
1704  }
1705 }
1706 
1707 
1708 
1709 void
1711 volume_heat_source_residual(bool request_jacobian,
1712  RealVectorX& f,
1713  RealMatrixX& jac,
1715 
1716 
1717  // get the function from this boundary condition
1719  &func = bc.get<MAST::FieldFunction<Real> >("heat_source"),
1720  *section = _property.section(*this);
1721 
1722  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1723 
1724  const std::vector<Real> &JxW = fe->get_JxW();
1725  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1726  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1727  const unsigned int n_phi = (unsigned int)phi.size();
1728 
1729  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1730  Real source, th;
1731 
1732  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1733 
1734  // now set the shape function values
1735  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1736  phi_vec(i_nd) = phi[i_nd][qp];
1737 
1738  // get the value of heat source
1739  func(qpoint[qp], _time, source);
1740  if (section) (*section)(qpoint[qp], _time, th);
1741  else th = 1.;
1742 
1743  f -= JxW[qp] * phi_vec * source * th;
1744  }
1745 }
1746 
1747 
1748 
1749 void
1752  RealVectorX& f,
1754 
1755  // get the function from this boundary condition
1757  &func = bc.get<MAST::FieldFunction<Real> >("heat_source"),
1758  *section = _property.section(*this);
1759 
1760  std::unique_ptr<MAST::FEBase> fe(_elem.init_fe(false, false));
1761 
1762  const std::vector<Real> &JxW = fe->get_JxW();
1763  const std::vector<libMesh::Point>& qpoint = fe->get_xyz();
1764  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1765  const unsigned int n_phi = (unsigned int)phi.size();
1766 
1767  RealVectorX phi_vec = RealVectorX::Zero(n_phi);
1768  Real source, dsource, th, dth;
1769 
1770  for (unsigned int qp=0; qp<qpoint.size(); qp++) {
1771 
1772  // now set the shape function values
1773  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1774  phi_vec(i_nd) = phi[i_nd][qp];
1775 
1776  // get the value of heat source
1777  func(qpoint[qp], _time, source);
1778  func.derivative(p, qpoint[qp], _time, dsource);
1779  if (section) {
1780 
1781  (*section)(qpoint[qp], _time, th);
1782  section->derivative(p, qpoint[qp], _time, dth);
1783  }
1784  else {
1785  th = 1.;
1786  dth = 0.;
1787  }
1788 
1789  f -= JxW[qp] * phi_vec * (dsource * th + source * dth);
1790  }
1791 }
1792 
1793 
1794 void
1797  RealVectorX& f,
1798  const unsigned int s,
1799  const MAST::FieldFunction<RealVectorX>& vel_f,
1801 
1802  // prepare the side finite element
1803  std::unique_ptr<MAST::FEBase> fe(_elem.init_side_fe(s, false, false));
1804 
1805  std::vector<Real> JxW_Vn = fe->get_JxW();
1806  const std::vector<libMesh::Point>& xyz = fe->get_xyz();
1807  const std::vector<libMesh::Point>& face_normals = fe->get_normals_for_local_coordinate();
1808  const std::vector<std::vector<Real> >& phi = fe->get_phi();
1809 
1810  // get the function from this boundary condition
1812  &func = bc.get<MAST::FieldFunction<Real> >("heat_source"),
1813  *section = _property.section(*this);
1814 
1815  const unsigned int
1816  n_phi = (unsigned int)phi.size(),
1817  dim = _elem.dim();
1818 
1819  RealVectorX
1820  phi_vec = RealVectorX::Zero(n_phi),
1821  vel = RealVectorX::Zero(dim);
1822  Real
1823  source = 0.,
1824  th = 0.,
1825  vn = 0.;
1826 
1827  // modify the JxW_Vn by multiplying the normal velocity to it
1828  for (unsigned int qp=0; qp<JxW_Vn.size(); qp++) {
1829 
1830  vel_f.derivative(p, xyz[qp], _time, vel);
1831  vn = 0.;
1832  for (unsigned int i=0; i<dim; i++)
1833  vn += vel(i)*face_normals[qp](i);
1834  JxW_Vn[qp] *= vn;
1835  }
1836 
1837  for (unsigned int qp=0; qp<xyz.size(); qp++) {
1838 
1839  // now set the shape function values
1840  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1841  phi_vec(i_nd) = phi[i_nd][qp];
1842 
1843  // get the value of heat source
1844  func(xyz[qp], _time, source);
1845  if (section) (*section)(xyz[qp], _time, th);
1846  else th = 1.;
1847 
1848  f -= JxW_Vn[qp] * phi_vec * source * th;
1849  }
1850 }
1851 
1852 
1853 
1854 
1855 void
1857 _initialize_mass_fem_operator(const unsigned int qp,
1858  const MAST::FEBase& fe,
1859  MAST::FEMOperatorMatrix& Bmat) {
1860 
1861  const std::vector<std::vector<Real> >& phi_fe = fe.get_phi();
1862 
1863  const unsigned int n_phi = (unsigned int)phi_fe.size();
1864 
1865  RealVectorX phi = RealVectorX::Zero(n_phi);
1866 
1867  // shape function values
1868  // N
1869  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1870  phi(i_nd) = phi_fe[i_nd][qp];
1871 
1872  Bmat.reinit(1, phi);
1873 }
1874 
1875 
1876 
1877 
1878 void
1881  const unsigned int dim,
1882  const MAST::FEBase& fe,
1883  std::vector<MAST::FEMOperatorMatrix>& dBmat) {
1884 
1885  libmesh_assert(dBmat.size() == dim);
1886 
1887  const std::vector<std::vector<libMesh::RealVectorValue> >& dphi = fe.get_dphi();
1888 
1889  const unsigned int n_phi = (unsigned int)dphi.size();
1890  RealVectorX phi = RealVectorX::Zero(n_phi);
1891 
1892  // now set the shape function values
1893  for (unsigned int i_dim=0; i_dim<dim; i_dim++) {
1894 
1895  for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ )
1896  phi(i_nd) = dphi[i_nd][qp](i_dim);
1897  dBmat[i_dim].reinit(1, phi); // dT/dx_i
1898  }
1899 }
1900 
virtual void surface_convection_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector sensitivity and Jacobian due to surface convection.
void _initialize_mass_fem_operator(const unsigned int qp, const MAST::FEBase &fe, MAST::FEMOperatorMatrix &Bmat)
When mass = false, initializes the FEM operator matrix to the shape functions as .
MAST::FunctionBase * _active_sol_function
pointer to the active solution mesh field function.
Definition: elem_base.h:213
virtual void external_side_loads_for_quadrature_elem(std::multimap< libMesh::boundary_id_type, MAST::BoundaryConditionBase *> &bc, std::map< unsigned int, std::vector< MAST::BoundaryConditionBase *>> &loads) const
From the given list of boundary loads, this identifies the sides of the quadrature element and the lo...
Definition: geom_elem.cpp:183
virtual void volume_heat_source_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to volume heat source.
const MAST::GeomElem & _elem
geometric element for which the computations are performed
Definition: elem_base.h:205
virtual const libMesh::Elem & get_reference_elem() const
Definition: geom_elem.cpp:54
virtual std::unique_ptr< MAST::FieldFunction< RealMatrixX > > thermal_capacitance_matrix(const MAST::ElementBase &e) const =0
virtual void internal_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac)
internal force contribution to system residual
virtual void surface_flux_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector sensitivity and Jacobian due to surface flux on element side s...
void reinit(unsigned int n_interpolated_vars, unsigned int n_discrete_vars, unsigned int n_discrete_dofs_per_var)
this initializes the operator for number of rows and variables, assuming that all variables has the s...
This provides a wrapper FieldFunction compatible class that interpolates the solution using libMesh&#39;s...
virtual void surface_flux_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface flux on element side s.
virtual const MAST::FieldFunction< Real > * section(const MAST::ElementBase &e) const =0
virtual void derivative(const MAST::FunctionBase &f, const libMesh::Point &p, const Real t, RealVectorX &v) const
calculates the value of the function at the specified point, p, and time, t, and returns it in v...
virtual void volume_heat_source_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to volume heat source on element volumetric domain...
RealVectorX _vel
local velocity
Definition: elem_base.h:260
This is a scalar function whose value can be changed and one that can be used as a design variable in...
Definition: parameter.h:35
virtual void derivative(const MAST::FunctionBase &f, ValType &v) const
calculates the value of the function derivative and returns it in v.
libMesh::Real Real
virtual const std::vector< std::vector< libMesh::RealVectorValue > > & get_dphi() const
Definition: fe_base.cpp:255
virtual const std::vector< std::vector< Real > > & get_phi() const
Definition: fe_base.cpp:247
virtual void internal_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f)
sensitivity of the internal force contribution to system residual
HeatConductionElementBase(MAST::SystemInitialization &sys, const MAST::GeomElem &elem, const MAST::ElementPropertyCardBase &p)
Constructor.
virtual std::unique_ptr< MAST::FEBase > init_fe(bool init_grads, bool init_second_order_derivative, int extra_quadrature_order=0) const
initializes the finite element shape function and quadrature object with the order of quadrature rule...
Definition: geom_elem.cpp:148
void _initialize_fem_gradient_operator(const unsigned int qp, const unsigned int dim, const MAST::FEBase &fe, std::vector< MAST::FEMOperatorMatrix > &dBmat)
For mass = true, the FEM operator matrix is initilized to the weak form of the Laplacian ...
void side_external_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, std::multimap< libMesh::boundary_id_type, MAST::BoundaryConditionBase *> &bc)
side external force contribution to system residual
virtual void surface_radiation_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface flux on element volumetric domain...
Matrix< Real, Dynamic, Dynamic > RealMatrixX
void right_multiply(T &r, const T &m) const
[R] = [this] * [M]
virtual void surface_convection_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface convection.
virtual std::unique_ptr< MAST::FieldFunction< RealMatrixX > > thermal_conductance_matrix(const MAST::ElementBase &e) const =0
void vector_mult_transpose(T &res, const T &v) const
res = v^T * [this]
Matrix< Real, Dynamic, 1 > RealVectorX
void right_multiply_transpose(T &r, const T &m) const
[R] = [this]^T * [M]
virtual void surface_convection_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface flux on element volumetric domain...
virtual void volume_heat_source_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to volume heat source.
void side_external_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, std::multimap< libMesh::boundary_id_type, MAST::BoundaryConditionBase *> &bc)
sensitivity of the side external force contribution to system residual
RealVectorX _sol
local solution
Definition: elem_base.h:225
This class acts as a wrapper around libMesh::Elem for the purpose of providing a uniform interface fo...
Definition: geom_elem.h:59
unsigned int dim() const
Definition: geom_elem.cpp:91
bool if_diagonal_mass_matrix() const
returns the type of strain to be used for this element
const ValType & get(const std::string &nm) const
returns a constant reference to the specified function
void volume_external_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, std::multimap< libMesh::subdomain_id_type, MAST::BoundaryConditionBase *> &bc)
volume external force contribution to system residual
void volume_external_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, std::multimap< libMesh::subdomain_id_type, MAST::BoundaryConditionBase *> &bc)
sensitivity of the volume external force contribution to system residual
virtual std::unique_ptr< MAST::FEBase > init_side_fe(unsigned int s, bool init_grads, bool init_second_order_derivative, int extra_quadrature_order=0) const
initializes the finite element shape function and quadrature object for the side with the order of qu...
Definition: geom_elem.cpp:165
void volume_external_residual_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f, std::multimap< libMesh::subdomain_id_type, MAST::BoundaryConditionBase *> &bc)
boundary velocity contribution of volume external force.
virtual void surface_flux_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface flux on element volumetric domain...
virtual void velocity_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac_xdot, RealMatrixX &jac)
inertial force contribution to system residual
virtual void surface_radiation_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector sensitivity and Jacobian due to surface radiation flux on element side...
virtual void velocity_residual_sensitivity(const MAST::FunctionBase &p, RealVectorX &f)
sensitivity of the damping force contribution to system residual
const Real & _time
time for which system is being assembled
Definition: elem_base.h:219
virtual void internal_residual_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f)
sensitivity of the internal force contribution to system residual
virtual void surface_radiation_residual(bool request_jacobian, RealVectorX &f, RealMatrixX &jac, const unsigned int s, MAST::BoundaryConditionBase &bc)
Calculates the residual vector and Jacobian due to surface radiation flux on side s...
const MAST::ElementPropertyCardBase & _property
element property
virtual void velocity_residual_boundary_velocity(const MAST::FunctionBase &p, RealVectorX &f, const unsigned int s, const MAST::FieldFunction< RealVectorX > &vel_f)
sensitivity of the internal force contribution to system residual
This is the base class for elements that implement calculation of finite element quantities over the ...
Definition: elem_base.h:72