Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fem_context.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #include "libmesh/fem_context.h"
21 
22 #include "libmesh/boundary_info.h"
23 #include "libmesh/diff_system.h"
24 #include "libmesh/dof_map.h"
25 #include "libmesh/elem.h"
26 #include "libmesh/fe_base.h"
27 #include "libmesh/fe_interface.h"
28 #include "libmesh/libmesh_logging.h"
29 #include "libmesh/mesh_base.h"
30 #include "libmesh/numeric_vector.h"
31 #include "libmesh/quadrature.h"
32 #include "libmesh/system.h"
33 #include "libmesh/time_solver.h"
34 #include "libmesh/unsteady_solver.h" // For euler_residual
35 
36 namespace libMesh
37 {
38 
40  const std::vector<unsigned int> * active_vars,
41  bool allocate_local_matrices)
42  : FEMContext(sys, sys.extra_quadrature_order, active_vars,
43  allocate_local_matrices)
44 {
45  init_internal_data(sys);
46 }
47 
49  int extra_quadrature_order,
50  const std::vector<unsigned int> * active_vars,
51  bool allocate_local_matrices)
52  : DiffContext(sys, allocate_local_matrices),
53  side(0), edge(0),
54  _mesh_sys(nullptr),
55  _mesh_x_var(0),
56  _mesh_y_var(0),
57  _mesh_z_var(0),
58  _atype(CURRENT),
59  _custom_solution(nullptr),
60  _boundary_info(sys.get_mesh().get_boundary_info()),
61  _elem(nullptr),
62  _dim(cast_int<unsigned char>(sys.get_mesh().mesh_dimension())),
63  _elem_dim(0), /* This will be reset in set_elem(). */
64  _elem_dims(sys.get_mesh().elem_dimensions()),
65  _element_qrule(4),
66  _side_qrule(4),
67  _extra_quadrature_order(extra_quadrature_order)
68 {
69  if (active_vars)
70  {
71  libmesh_assert(!active_vars->empty());
72  auto vars_copy =
73  std::make_unique<std::vector<unsigned int>>(*active_vars);
74 
75  // We want to do quick binary_search later
76  std::sort(vars_copy->begin(), vars_copy->end());
77 
78  _active_vars = std::move(vars_copy);
79  }
80 
81  init_internal_data(sys);
82 }
83 
84 
85 
87 {
88  const System & sys = this->get_system();
89  FEType hardest_fe_type =
91  (*_active_vars)[0] : 0);
92 
93  auto check_var = [&hardest_fe_type, &sys](unsigned int v)
94  {
95  FEType fe_type = sys.variable_type(v);
96 
97  // Make sure we find a non-SCALAR FE family, even in the case
98  // where the first variable(s) weren't
99  if (hardest_fe_type.family == SCALAR)
100  {
101  hardest_fe_type.family = fe_type.family;
102  hardest_fe_type.order = fe_type.order;
103  }
104 
105  // FIXME - we don't yet handle mixed finite elements from
106  // different families which require different quadrature rules
107  // libmesh_assert_equal_to (fe_type.family, hardest_fe_type.family);
108 
109  // We need to detect SCALAR's so we can prepare FE objects for
110  // them, and so we don't mistake high order scalars as a reason
111  // to crank up the quadrature order on other types.
112  if (fe_type.family != SCALAR && fe_type.order > hardest_fe_type.order)
113  hardest_fe_type = fe_type;
114  };
115 
116  if (_active_vars)
117  for (auto v : *_active_vars)
118  check_var(v);
119  else
120  for (auto v : make_range(sys.n_vars()))
121  check_var(v);
122 
123  return hardest_fe_type;
124 }
125 
126 
128 {
129  const System & sys = this->get_system();
130 
131  auto attach_rules = [this, &sys](unsigned int v)
132  {
133  for (const auto & dim : _elem_dims)
134  {
135  FEType fe_type = sys.variable_type(v);
136 
137  _element_fe[dim][fe_type]->attach_quadrature_rule(_element_qrule[dim].get());
138  if (dim)
139  _side_fe[dim][fe_type]->attach_quadrature_rule(_side_qrule[dim].get());
140  if (dim == 3)
141  _edge_fe[fe_type]->attach_quadrature_rule(_edge_qrule.get());
142  };
143  };
144 
145  if (_active_vars)
146  for (auto v : *_active_vars)
147  attach_rules(v);
148  else
149  for (auto v : make_range(sys.n_vars()))
150  attach_rules(v);
151 }
152 
153 
154 
155 void FEMContext::use_default_quadrature_rules(int extra_quadrature_order)
156 {
157  _extra_quadrature_order = extra_quadrature_order;
158 
159  FEType hardest_fe_type = this->find_hardest_fe_type();
160 
161  for (const auto & dim : _elem_dims)
162  {
163  // Create an adequate quadrature rule
166  if (dim)
167  _side_qrule[dim] =
169  if (dim == 3)
171  }
172 
173  this->attach_quadrature_rules();
174 }
175 
176 
177 void FEMContext::use_unweighted_quadrature_rules(int extra_quadrature_order)
178 {
179  _extra_quadrature_order = extra_quadrature_order;
180 
181  FEType hardest_fe_type = this->find_hardest_fe_type();
182 
183  for (const auto & dim : _elem_dims)
184  {
185  // Create an adequate quadrature rule
188  _side_qrule[dim] =
190  if (dim == 3)
192  }
193 
194  this->attach_quadrature_rules();
195 }
196 
197 
199 {
200  // Reserve space for the FEAbstract and QBase objects for each
201  // element dimension possibility (0,1,2,3)
202 
203  // Note: we would simply resize() all four of these vectors, but
204  // some compilers (ICC 19, MSVC) generate a diagnostic about copying
205  // a std::unique_ptr in this case, so the following two lines are a
206  // workaround.
207  _element_fe = std::vector<std::map<FEType, std::unique_ptr<FEAbstract>>>(4);
208  _side_fe = std::vector<std::map<FEType, std::unique_ptr<FEAbstract>>>(4);
209  _element_fe_var.resize(4);
210  _side_fe_var.resize(4);
211 
212  // We need to know which of our variables has the hardest
213  // shape functions to numerically integrate.
214 
215  unsigned int nv = sys.n_vars();
216  libmesh_assert (nv);
217 
218  bool have_scalar = false;
219 
220  if (_active_vars)
221  {
222  for (auto v : *_active_vars)
223  if (sys.variable_type(v).family == SCALAR)
224  {
225  have_scalar = true;
226  break;
227  }
228  }
229  else
230  {
231  for (auto v : make_range(sys.n_vars()))
232  if (sys.variable_type(v).family == SCALAR)
233  {
234  have_scalar = true;
235  break;
236  }
237  }
238 
239  if (have_scalar)
240  // SCALAR FEs have dimension 0 by assumption
241  _elem_dims.insert(0);
242 
243  auto build_var_fe = [this, &sys](unsigned int dim,
244  unsigned int i)
245  {
246  FEType fe_type = sys.variable_type(i);
247  const auto & dof_map = sys.get_dof_map();
248  const bool add_p_level = dof_map.should_p_refine(dof_map.var_group_from_var_number(i));
249 
250  auto & element_fe = _element_fe[dim][fe_type];
251  auto & side_fe = _side_fe[dim][fe_type];
252  if (!element_fe)
253  {
254  element_fe = FEAbstract::build(dim, fe_type);
255  element_fe->add_p_level_in_reinit(add_p_level);
256  side_fe = FEAbstract::build(dim, fe_type);
257  side_fe->add_p_level_in_reinit(add_p_level);
258 
259  if (dim == 3)
260  {
261  auto & edge_fe = _edge_fe[fe_type];
262  edge_fe = FEAbstract::build(dim, fe_type);
263  edge_fe->add_p_level_in_reinit(add_p_level);
264  }
265  }
266 
267  _element_fe_var[dim][i] = element_fe.get();
268  _side_fe_var[dim][i] = side_fe.get();
269  if ((dim) == 3)
270  _edge_fe_var[i] = _edge_fe[fe_type].get();
271  };
272 
273  for (const auto & dim : _elem_dims)
274  {
275  // Create finite element objects
276  _element_fe_var[dim].resize(nv);
277  _side_fe_var[dim].resize(nv);
278  if (dim == 3)
279  _edge_fe_var.resize(nv);
280 
281  if (_active_vars)
282  for (auto v : *_active_vars)
283  build_var_fe(dim, v);
284  else
285  for (auto v : make_range(nv))
286  build_var_fe(dim, v);
287  }
288 
290 }
291 
293 {
294 }
295 
296 
297 
299 {
300  return _boundary_info.has_boundary_id(&(this->get_elem()), side, id);
301 }
302 
303 
304 
305 void FEMContext::side_boundary_ids(std::vector<boundary_id_type> & vec_to_fill) const
306 {
307  _boundary_info.boundary_ids(&(this->get_elem()), side, vec_to_fill);
308 }
309 
310 
311 
312 template<typename OutputType,
314  FEMContext::diff_subsolution_getter subsolution_getter>
315 void FEMContext::some_value(unsigned int var, unsigned int qp, OutputType & u) const
316 {
317  // Get local-to-global dof index lookup
318  const unsigned int n_dofs = cast_int<unsigned int>
319  (this->get_dof_indices(var).size());
320 
321  // Get current local coefficients
322  const DenseSubVector<Number> & coef = (this->*subsolution_getter)(var);
323  libmesh_assert_equal_to(coef.size(), n_dofs);
324 
325  // Get finite element object
326  typename FENeeded<OutputType>::value_base * fe = nullptr;
327  (this->*fe_getter)( var, fe, this->get_elem_dim() );
328 
329  // Get shape function values at quadrature point
330  const std::vector<std::vector
331  <typename FENeeded<OutputType>::value_shape>> & phi = fe->get_phi();
332  libmesh_assert_equal_to(phi.size(), n_dofs);
333 
334  // Accumulate solution value
335  u = 0.;
336 
337  for (unsigned int l=0; l != n_dofs; l++)
338  {
339  libmesh_assert_less(qp, phi[l].size());
340  u += phi[l][qp] * coef(l);
341  }
342 }
343 
344 
345 
346 template<typename OutputType,
348  FEMContext::diff_subsolution_getter subsolution_getter>
349 void FEMContext::some_gradient(unsigned int var, unsigned int qp, OutputType & du) const
350 {
351  // Get local-to-global dof index lookup
352  const unsigned int n_dofs = cast_int<unsigned int>
353  (this->get_dof_indices(var).size());
354 
355  // Get current local coefficients
356  const DenseSubVector<Number> & coef = (this->*subsolution_getter)(var);
357 
358  // Get finite element object
359  typename FENeeded<OutputType>::grad_base * fe = nullptr;
360  (this->*fe_getter)( var, fe, this->get_elem_dim() );
361 
362  // Get shape function values at quadrature point
363  const std::vector<std::vector
365  & dphi = fe->get_dphi();
366 
367  // Accumulate solution derivatives
368  du = 0;
369 
370  for (unsigned int l=0; l != n_dofs; l++)
371  du.add_scaled(dphi[l][qp], coef(l));
372 
373  return;
374 }
375 
376 
377 
378 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
379 template<typename OutputType,
381  FEMContext::diff_subsolution_getter subsolution_getter>
382 void FEMContext::some_hessian(unsigned int var, unsigned int qp, OutputType & d2u) const
383 {
384  // Get local-to-global dof index lookup
385  const unsigned int n_dofs = cast_int<unsigned int>
386  (this->get_dof_indices(var).size());
387 
388  // Get current local coefficients
389  const DenseSubVector<Number> & coef = (this->*subsolution_getter)(var);
390 
391  // Get finite element object
392  typename FENeeded<OutputType>::hess_base * fe = nullptr;
393  (this->*fe_getter)( var, fe, this->get_elem_dim() );
394 
395  // Get shape function values at quadrature point
396  const std::vector<std::vector
398  & d2phi = fe->get_d2phi();
399 
400  // Accumulate solution second derivatives
401  d2u = 0.0;
402 
403  for (unsigned int l=0; l != n_dofs; l++)
404  d2u.add_scaled(d2phi[l][qp], coef(l));
405 
406  return;
407 }
408 #endif
409 
410 
411 
412 Number FEMContext::interior_value(unsigned int var, unsigned int qp) const
413 {
414  Number u;
415 
416  this->interior_value( var, qp, u );
417 
418  return u;
419 }
420 
421 template<typename OutputType>
422 void FEMContext::interior_value(unsigned int var, unsigned int qp,
423  OutputType & u) const
424 {
425  this->some_value<OutputType,
426  &FEMContext::get_element_fe<typename TensorTools::MakeReal<OutputType>::type>,
427  &DiffContext::get_elem_solution>(var, qp, u);
428 }
429 
430 
431 template<typename OutputType>
432 void FEMContext::interior_values (unsigned int var,
433  const NumericVector<Number> & _system_vector,
434  std::vector<OutputType> & u_vals) const
435 {
436  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
437 
438  // Get local-to-global dof index lookup
439  const unsigned int n_dofs = cast_int<unsigned int>
440  (this->get_dof_indices(var).size());
441 
442  // Get current local coefficients
443  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
444 
445  // Get the finite element object
446  FEGenericBase<OutputShape> * fe = nullptr;
447  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
448 
449  // Get shape function values at quadrature point
450  const std::vector<std::vector<OutputShape>> & phi = fe->get_phi();
451 
452  // Loop over all the q_points on this element
453  for (auto qp : index_range(u_vals))
454  {
455  OutputType & u = u_vals[qp];
456 
457  // Compute the value at this q_point
458  u = 0.;
459 
460  for (unsigned int l=0; l != n_dofs; l++)
461  u += phi[l][qp] * coef(l);
462  }
463 
464  return;
465 }
466 
468  unsigned int qp) const
469 {
470  Gradient du;
471 
472  this->interior_gradient( var, qp, du );
473 
474  return du;
475 }
476 
477 
478 
479 template<typename OutputType>
480 void FEMContext::interior_gradient(unsigned int var,
481  unsigned int qp,
482  OutputType & du) const
483 {
484  this->some_gradient<OutputType,
487  <OutputType>::type>::type>,
488  &DiffContext::get_elem_solution>(var, qp, du);
489 }
490 
491 
492 
493 template<typename OutputType>
494 void FEMContext::interior_gradients(unsigned int var,
495  const NumericVector<Number> & _system_vector,
496  std::vector<OutputType> & du_vals) const
497 {
498  typedef typename TensorTools::MakeReal
500  OutputShape;
501 
502  // Get local-to-global dof index lookup
503  const unsigned int n_dofs = cast_int<unsigned int>
504  (this->get_dof_indices(var).size());
505 
506  // Get current local coefficients
507  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
508 
509  // Get finite element object
510  FEGenericBase<OutputShape> * fe = nullptr;
511  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
512 
513  // Get shape function values at quadrature point
514  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> & dphi = fe->get_dphi();
515 
516  // Loop over all the q_points in this finite element
517  for (auto qp : index_range(du_vals))
518  {
519  OutputType & du = du_vals[qp];
520 
521  // Compute the gradient at this q_point
522  du = 0;
523 
524  for (unsigned int l=0; l != n_dofs; l++)
525  du.add_scaled(dphi[l][qp], coef(l));
526  }
527 
528  return;
529 }
530 
531 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
532 Tensor FEMContext::interior_hessian(unsigned int var, unsigned int qp) const
533 {
534  Tensor d2u;
535 
536  this->interior_hessian( var, qp, d2u );
537 
538  return d2u;
539 }
540 
541 template<typename OutputType>
542 void FEMContext::interior_hessian(unsigned int var, unsigned int qp,
543  OutputType & d2u) const
544 {
545  this->some_hessian<OutputType,
547  <typename TensorTools::MakeReal
550  <OutputType>::type>::type>::type>,
551  &DiffContext::get_elem_solution>(var, qp, d2u);
552 }
553 
554 
555 template<typename OutputType>
556 void FEMContext::interior_hessians(unsigned int var,
557  const NumericVector<Number> & _system_vector,
558  std::vector<OutputType> & d2u_vals) const
559 {
560  typedef typename TensorTools::DecrementRank<OutputType>::type Rank1Decrement;
561  typedef typename TensorTools::DecrementRank<Rank1Decrement>::type Rank2Decrement;
562  typedef typename TensorTools::MakeReal<Rank2Decrement>::type OutputShape;
563 
564  // Get local-to-global dof index lookup
565  const unsigned int n_dofs = cast_int<unsigned int>
566  (this->get_dof_indices(var).size());
567 
568  // Get current local coefficients
569  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
570 
571  // Get finite element object
572  FEGenericBase<OutputShape> * fe = nullptr;
573  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
574 
575  // Get shape function values at quadrature point
576  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor>> & d2phi = fe->get_d2phi();
577 
578  // Loop over all the q_points in this finite element
579  for (auto qp : index_range(d2u_vals))
580  {
581  OutputType & d2u = d2u_vals[qp];
582 
583  // Compute the gradient at this q_point
584  d2u = 0;
585 
586  for (unsigned int l=0; l != n_dofs; l++)
587  d2u.add_scaled(d2phi[l][qp], coef(l));
588  }
589 
590  return;
591 }
592 
593 
594 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
595 
596 
597 template<typename OutputType>
598 void FEMContext::interior_curl(unsigned int var, unsigned int qp,
599  OutputType & curl_u) const
600 {
601  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
602 
603  // Get local-to-global dof index lookup
604  const unsigned int n_dofs = cast_int<unsigned int>
605  (this->get_dof_indices(var).size());
606 
607  // Get current local coefficients
608  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
609  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
610 
611  // Get finite element object
612  FEGenericBase<OutputShape> * fe = nullptr;
613  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
614 
615  // Get shape function values at quadrature point
616  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputShape>> & curl_phi = fe->get_curl_phi();
617 
618  // Accumulate solution curl
619  curl_u = 0.;
620 
621  for (unsigned int l=0; l != n_dofs; l++)
622  curl_u.add_scaled(curl_phi[l][qp], coef(l));
623 
624  return;
625 }
626 
627 
628 template<typename OutputType>
629 void FEMContext::interior_div(unsigned int var, unsigned int qp,
630  OutputType & div_u) const
631 {
632  typedef typename
634  <typename TensorTools::MakeReal<OutputType>::type>::type OutputShape;
635 
636  // Get local-to-global dof index lookup
637  const unsigned int n_dofs = cast_int<unsigned int>
638  (this->get_dof_indices(var).size());
639 
640  // Get current local coefficients
641  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
642  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
643 
644  // Get finite element object
645  FEGenericBase<OutputShape> * fe = nullptr;
646  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
647 
648  // Get shape function values at quadrature point
649  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputDivergence>> & div_phi = fe->get_div_phi();
650 
651  // Accumulate solution curl
652  div_u = 0.;
653 
654  for (unsigned int l=0; l != n_dofs; l++)
655  div_u += div_phi[l][qp] * coef(l);
656 
657  return;
658 }
659 
660 
662  unsigned int qp) const
663 {
664  Number u = 0.;
665 
666  this->side_value( var, qp, u );
667 
668  return u;
669 }
670 
671 
672 template<typename OutputType>
673 void FEMContext::side_value(unsigned int var,
674  unsigned int qp,
675  OutputType & u) const
676 {
677  this->some_value<OutputType,
678  &FEMContext::get_side_fe<typename TensorTools::MakeReal<OutputType>::type>,
679  &DiffContext::get_elem_solution>(var, qp, u);
680 }
681 
682 
683 template<typename OutputType>
684 void FEMContext::side_values(unsigned int var,
685  const NumericVector<Number> & _system_vector,
686  std::vector<OutputType> & u_vals) const
687 {
688  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
689 
690  // Get local-to-global dof index lookup
691  const unsigned int n_dofs = cast_int<unsigned int>
692  (this->get_dof_indices(var).size());
693 
694  // Get current local coefficients
695  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
696 
697  // Get the finite element object
698  FEGenericBase<OutputShape> * the_side_fe = nullptr;
699  this->get_side_fe<OutputShape>( var, the_side_fe, this->get_elem_dim() );
700 
701  // Get shape function values at quadrature point
702  const std::vector<std::vector<OutputShape>> & phi = the_side_fe->get_phi();
703 
704  // Loop over all the q_points on this element
705  for (auto qp : index_range(u_vals))
706  {
707  OutputType & u = u_vals[qp];
708 
709  // Compute the value at this q_point
710  u = 0.;
711 
712  for (unsigned int l=0; l != n_dofs; l++)
713  u += phi[l][qp] * coef(l);
714  }
715 
716  return;
717 }
718 
719 Gradient FEMContext::side_gradient(unsigned int var, unsigned int qp) const
720 {
721  Gradient du;
722 
723  this->side_gradient( var, qp, du );
724 
725  return du;
726 }
727 
728 
729 template<typename OutputType>
730 void FEMContext::side_gradient(unsigned int var, unsigned int qp,
731  OutputType & du) const
732 {
733  typedef typename TensorTools::MakeReal
735  OutputShape;
736 
737  // Get local-to-global dof index lookup
738  const unsigned int n_dofs = cast_int<unsigned int>
739  (this->get_dof_indices(var).size());
740 
741  // Get current local coefficients
742  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
743  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
744 
745  // Get finite element object
746  FEGenericBase<OutputShape> * the_side_fe = nullptr;
747  this->get_side_fe<OutputShape>( var, the_side_fe, this->get_elem_dim() );
748 
749  // Get shape function values at quadrature point
750  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> & dphi = the_side_fe->get_dphi();
751 
752  // Accumulate solution derivatives
753  du = 0.;
754 
755  for (unsigned int l=0; l != n_dofs; l++)
756  du.add_scaled(dphi[l][qp], coef(l));
757 
758  return;
759 }
760 
761 
762 
763 template<typename OutputType>
764 void FEMContext::side_gradients(unsigned int var,
765  const NumericVector<Number> & _system_vector,
766  std::vector<OutputType> & du_vals) const
767 {
768  typedef typename TensorTools::MakeReal
770  OutputShape;
771 
772  // Get local-to-global dof index lookup
773  const unsigned int n_dofs = cast_int<unsigned int>
774  (this->get_dof_indices(var).size());
775 
776  // Get current local coefficients
777  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
778 
779  // Get finite element object
780  FEGenericBase<OutputShape> * the_side_fe = nullptr;
781  this->get_side_fe<OutputShape>( var, the_side_fe, this->get_elem_dim() );
782 
783  // Get shape function values at quadrature point
784  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> & dphi = the_side_fe->get_dphi();
785 
786  // Loop over all the q_points in this finite element
787  for (auto qp : index_range(du_vals))
788  {
789  OutputType & du = du_vals[qp];
790 
791  du = 0;
792 
793  // Compute the gradient at this q_point
794  for (unsigned int l=0; l != n_dofs; l++)
795  du.add_scaled(dphi[l][qp], coef(l));
796  }
797 
798  return;
799 }
800 
801 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
803  unsigned int qp) const
804 {
805  Tensor d2u;
806 
807  this->side_hessian( var, qp, d2u );
808 
809  return d2u;
810 }
811 
812 
813 
814 template<typename OutputType>
815 void FEMContext::side_hessian(unsigned int var,
816  unsigned int qp,
817  OutputType & d2u) const
818 {
819  this->some_hessian<OutputType,
821  <typename TensorTools::MakeReal
824  <OutputType>::type>::type>::type>,
825  &DiffContext::get_elem_solution>(var, qp, d2u);
826 }
827 
828 
829 
830 template<typename OutputType>
831 void FEMContext::side_hessians(unsigned int var,
832  const NumericVector<Number> & _system_vector,
833  std::vector<OutputType> & d2u_vals) const
834 {
835  typedef typename TensorTools::DecrementRank<OutputType>::type Rank1Decrement;
836  typedef typename TensorTools::DecrementRank<Rank1Decrement>::type Rank2Decrement;
837  typedef typename TensorTools::MakeReal<Rank2Decrement>::type OutputShape;
838 
839  // Get local-to-global dof index lookup
840  const unsigned int n_dofs = cast_int<unsigned int>
841  (this->get_dof_indices(var).size());
842 
843  // Get current local coefficients
844  const DenseSubVector<Number> & coef = get_localized_subvector(_system_vector, var);
845 
846  // Get finite element object
847  FEGenericBase<OutputShape> * the_side_fe = nullptr;
848  this->get_side_fe<OutputShape>( var, the_side_fe, this->get_elem_dim() );
849 
850  // Get shape function values at quadrature point
851  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor>> & d2phi = the_side_fe->get_d2phi();
852 
853  // Loop over all the q_points in this finite element
854  for (auto qp : index_range(d2u_vals))
855  {
856  OutputType & d2u = d2u_vals[qp];
857 
858  // Compute the gradient at this q_point
859  d2u = 0;
860 
861  for (unsigned int l=0; l != n_dofs; l++)
862  d2u.add_scaled(d2phi[l][qp], coef(l));
863  }
864 
865  return;
866 }
867 
868 
869 
870 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
871 
872 
873 
874 Number FEMContext::point_value(unsigned int var, const Point & p) const
875 {
876  Number u = 0.;
877 
878  this->point_value( var, p, u );
879 
880  return u;
881 }
882 
883 template<typename OutputType>
884 void FEMContext::point_value(unsigned int var,
885  const Point & p,
886  OutputType & u,
887  const Real tolerance) const
888 {
889  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
890 
891  // Get local-to-global dof index lookup
892  const unsigned int n_dofs = cast_int<unsigned int>
893  (this->get_dof_indices(var).size());
894 
895  // Get current local coefficients
896  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
897  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
898 
899  // Get finite element object
900  FEGenericBase<OutputShape> * fe = nullptr;
901  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
902 
903  // Build a FE for calculating u(p)
904  FEGenericBase<OutputShape> * fe_new =
905  this->build_new_fe( fe, p, tolerance, 0 );
906 
907  // Get the values of the shape function derivatives
908  const std::vector<std::vector<OutputShape>> & phi = fe_new->get_phi();
909 
910  u = 0.;
911 
912  for (unsigned int l=0; l != n_dofs; l++)
913  u += phi[l][0] * coef(l);
914 
915  return;
916 }
917 
918 
919 
920 Gradient FEMContext::point_gradient(unsigned int var, const Point & p) const
921 {
922  Gradient grad_u;
923 
924  this->point_gradient( var, p, grad_u );
925 
926  return grad_u;
927 }
928 
929 
930 
931 template<typename OutputType>
932 void FEMContext::point_gradient(unsigned int var,
933  const Point & p,
934  OutputType & grad_u,
935  const Real tolerance) const
936 {
937  typedef typename TensorTools::MakeReal
939  OutputShape;
940 
941  // Get local-to-global dof index lookup
942  const unsigned int n_dofs = cast_int<unsigned int>
943  (this->get_dof_indices(var).size());
944 
945  // Get current local coefficients
946  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
947  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
948 
949  // Get finite element object
950  FEGenericBase<OutputShape> * fe = nullptr;
951  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
952 
953  // Build a FE for calculating u(p)
954  FEGenericBase<OutputShape> * fe_new =
955  this->build_new_fe( fe, p, tolerance, 1 );
956 
957  // Get the values of the shape function derivatives
958  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> & dphi = fe_new->get_dphi();
959 
960  grad_u = 0.0;
961 
962  for (unsigned int l=0; l != n_dofs; l++)
963  grad_u.add_scaled(dphi[l][0], coef(l));
964 
965  return;
966 }
967 
968 
969 
970 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
971 
972 Tensor FEMContext::point_hessian(unsigned int var, const Point & p) const
973 {
974  Tensor hess_u;
975 
976  this->point_hessian( var, p, hess_u );
977 
978  return hess_u;
979 }
980 
981 
982 template<typename OutputType>
983 void FEMContext::point_hessian(unsigned int var,
984  const Point & p,
985  OutputType & hess_u,
986  const Real tolerance) const
987 {
988  typedef typename TensorTools::DecrementRank<OutputType>::type Rank1Decrement;
989  typedef typename TensorTools::DecrementRank<Rank1Decrement>::type Rank2Decrement;
990  typedef typename TensorTools::MakeReal<Rank2Decrement>::type OutputShape;
991 
992  // Get local-to-global dof index lookup
993  const unsigned int n_dofs = cast_int<unsigned int>
994  (this->get_dof_indices(var).size());
995 
996  // Get current local coefficients
997  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
998  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
999 
1000  // Get finite element object
1001  FEGenericBase<OutputShape> * fe = nullptr;
1002  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
1003 
1004  // Build a FE for calculating u(p)
1005  FEGenericBase<OutputShape> * fe_new =
1006  this->build_new_fe( fe, p, tolerance, 2 );
1007 
1008  // Get the values of the shape function derivatives
1009  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor>> & d2phi = fe_new->get_d2phi();
1010 
1011  hess_u = 0.0;
1012 
1013  for (unsigned int l=0; l != n_dofs; l++)
1014  hess_u.add_scaled(d2phi[l][0], coef(l));
1015 
1016  return;
1017 }
1018 
1019 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
1020 
1021 
1022 template<typename OutputType>
1023 void FEMContext::point_curl(unsigned int var,
1024  const Point & p,
1025  OutputType & curl_u,
1026  const Real tolerance) const
1027 {
1028  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
1029 
1030  // Get local-to-global dof index lookup
1031  const unsigned int n_dofs = cast_int<unsigned int>
1032  (this->get_dof_indices(var).size());
1033 
1034  // Get current local coefficients
1035  libmesh_assert_greater (this->_elem_subsolutions.size(), var);
1036  const DenseSubVector<Number> & coef = this->get_elem_solution(var);
1037 
1038  // Get finite element object
1039  FEGenericBase<OutputShape> * fe = nullptr;
1040  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
1041 
1042  // Build a FE for calculating u(p)
1043  FEGenericBase<OutputShape> * fe_new =
1044  this->build_new_fe( fe, p, tolerance, 3 );
1045 
1046  // Get the values of the shape function derivatives
1047  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputShape>> & curl_phi = fe_new->get_curl_phi();
1048 
1049  curl_u = 0.0;
1050 
1051  for (unsigned int l=0; l != n_dofs; l++)
1052  curl_u.add_scaled(curl_phi[l][0], coef(l));
1053 
1054  return;
1055 }
1056 
1057 
1058 
1059 Number FEMContext::fixed_interior_value(unsigned int var, unsigned int qp) const
1060 {
1061  Number u = 0.;
1062 
1063  this->fixed_interior_value( var, qp, u );
1064 
1065  return u;
1066 }
1067 
1068 
1069 
1070 template<typename OutputType>
1071 void FEMContext::fixed_interior_value(unsigned int var, unsigned int qp,
1072  OutputType & u) const
1073 {
1074  this->some_value<OutputType,
1078 }
1079 
1080 
1081 
1082 Gradient FEMContext::fixed_interior_gradient(unsigned int var, unsigned int qp) const
1083 {
1084  Gradient du;
1085 
1086  this->fixed_interior_gradient( var, qp, du );
1087 
1088  return du;
1089 }
1090 
1091 
1092 template<typename OutputType>
1093 void FEMContext::fixed_interior_gradient(unsigned int var, unsigned int qp,
1094  OutputType & du) const
1095 {
1096  this->some_gradient
1097  <OutputType,
1099  <typename TensorTools::MakeReal
1100  <typename TensorTools::DecrementRank
1101  <OutputType>::type>::type>,
1103  (var, qp, du);
1104 }
1105 
1106 
1107 
1108 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
1109 Tensor FEMContext::fixed_interior_hessian(unsigned int var, unsigned int qp) const
1110 {
1111  Tensor d2u;
1112 
1113  this->fixed_interior_hessian( var, qp, d2u );
1114 
1115  return d2u;
1116 }
1117 
1118 
1119 template<typename OutputType>
1120 void FEMContext::fixed_interior_hessian(unsigned int var, unsigned int qp,
1121  OutputType & d2u) const
1122 {
1123  this->some_hessian<OutputType,
1125  <typename TensorTools::MakeReal
1126  <typename TensorTools::DecrementRank
1127  <typename TensorTools::DecrementRank
1128  <OutputType>::type>::type>::type>,
1129  &DiffContext::get_elem_fixed_solution>(var, qp, d2u);
1130 }
1131 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
1132 
1133 
1134 
1135 Number FEMContext::fixed_side_value(unsigned int var, unsigned int qp) const
1136 {
1137  Number u = 0.;
1138 
1139  this->fixed_side_value( var, qp, u );
1140 
1141  return u;
1142 }
1143 
1144 
1145 template<typename OutputType>
1146 void FEMContext::fixed_side_value(unsigned int var, unsigned int qp,
1147  OutputType & u) const
1148 {
1149  this->some_value
1150  <OutputType,
1154  (var, qp, u);
1155 }
1156 
1157 
1158 
1159 Gradient FEMContext::fixed_side_gradient(unsigned int var, unsigned int qp) const
1160 {
1161  Gradient du;
1162 
1163  this->fixed_side_gradient( var, qp, du );
1164 
1165  return du;
1166 }
1167 
1168 
1169 template<typename OutputType>
1170 void FEMContext::fixed_side_gradient(unsigned int var, unsigned int qp,
1171  OutputType & du) const
1172 {
1173  this->some_gradient<OutputType,
1175  <typename TensorTools::MakeReal
1176  <typename TensorTools::DecrementRank
1177  <OutputType>::type>::type>,
1178  &DiffContext::get_elem_fixed_solution>(var, qp, du);
1179 }
1180 
1181 
1182 
1183 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
1184 Tensor FEMContext::fixed_side_hessian(unsigned int var, unsigned int qp) const
1185 {
1186  Tensor d2u;
1187 
1188  this->fixed_side_hessian( var, qp, d2u );
1189 
1190  return d2u;
1191 }
1192 
1193 template<typename OutputType>
1194 void FEMContext::fixed_side_hessian(unsigned int var, unsigned int qp,
1195  OutputType & d2u) const
1196 {
1197  this->some_hessian<OutputType,
1199  <typename TensorTools::MakeReal
1200  <typename TensorTools::DecrementRank
1201  <typename TensorTools::DecrementRank
1202  <OutputType>::type>::type>::type>,
1203  &DiffContext::get_elem_fixed_solution>(var, qp, d2u);
1204 }
1205 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
1206 
1207 
1208 
1209 Number FEMContext::fixed_point_value(unsigned int var, const Point & p) const
1210 {
1211  Number u = 0.;
1212 
1213  this->fixed_point_value( var, p, u );
1214 
1215  return u;
1216 }
1217 
1218 template<typename OutputType>
1219 void FEMContext::fixed_point_value(unsigned int var,
1220  const Point & p,
1221  OutputType & u,
1222  const Real tolerance) const
1223 {
1224  typedef typename TensorTools::MakeReal<OutputType>::type OutputShape;
1225 
1226  // Get local-to-global dof index lookup
1227  const unsigned int n_dofs = cast_int<unsigned int>
1228  (this->get_dof_indices(var).size());
1229 
1230  // Get current local coefficients
1231  libmesh_assert_greater (_elem_fixed_subsolutions.size(), var);
1232  const DenseSubVector<Number> & coef = this->get_elem_fixed_solution(var);
1233 
1234  // Get finite element object
1235  FEGenericBase<OutputShape> * fe = nullptr;
1236  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
1237 
1238  // Build a FE for calculating u(p)
1239  FEGenericBase<OutputShape> * fe_new =
1240  this->build_new_fe( fe, p, tolerance, 0 );
1241 
1242  // Get the values of the shape function derivatives
1243  const std::vector<std::vector<OutputShape>> & phi = fe_new->get_phi();
1244 
1245  u = 0.;
1246 
1247  for (unsigned int l=0; l != n_dofs; l++)
1248  u += phi[l][0] * coef(l);
1249 
1250  return;
1251 }
1252 
1253 
1254 
1255 Gradient FEMContext::fixed_point_gradient(unsigned int var, const Point & p) const
1256 {
1257  Gradient grad_u;
1258 
1259  this->fixed_point_gradient( var, p, grad_u );
1260 
1261  return grad_u;
1262 }
1263 
1264 
1265 
1266 template<typename OutputType>
1267 void FEMContext::fixed_point_gradient(unsigned int var,
1268  const Point & p,
1269  OutputType & grad_u,
1270  const Real tolerance) const
1271 {
1272  typedef typename TensorTools::MakeReal
1274  OutputShape;
1275 
1276  // Get local-to-global dof index lookup
1277  const unsigned int n_dofs = cast_int<unsigned int>
1278  (this->get_dof_indices(var).size());
1279 
1280  // Get current local coefficients
1281  libmesh_assert_greater (_elem_fixed_subsolutions.size(), var);
1282  const DenseSubVector<Number> & coef = this->get_elem_fixed_solution(var);
1283 
1284  // Get finite element object
1285  FEGenericBase<OutputShape> * fe = nullptr;
1286  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
1287 
1288  // Build a FE for calculating u(p)
1289  FEGenericBase<OutputShape> * fe_new =
1290  this->build_new_fe( fe, p, tolerance, 1 );
1291 
1292  // Get the values of the shape function derivatives
1293  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> & dphi = fe_new->get_dphi();
1294 
1295  grad_u = 0.0;
1296 
1297  for (unsigned int l=0; l != n_dofs; l++)
1298  grad_u.add_scaled(dphi[l][0], coef(l));
1299 
1300  return;
1301 }
1302 
1303 
1304 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
1305 
1306 Tensor FEMContext::fixed_point_hessian(unsigned int var, const Point & p) const
1307 {
1308  Tensor hess_u;
1309 
1310  this->fixed_point_hessian( var, p, hess_u );
1311 
1312  return hess_u;
1313 }
1314 
1315 
1316 
1317 template<typename OutputType>
1318 void FEMContext::fixed_point_hessian(unsigned int var,
1319  const Point & p,
1320  OutputType & hess_u,
1321  const Real tolerance) const
1322 {
1323  typedef typename TensorTools::DecrementRank<OutputType>::type Rank1Decrement;
1324  typedef typename TensorTools::DecrementRank<Rank1Decrement>::type Rank2Decrement;
1325  typedef typename TensorTools::MakeReal<Rank2Decrement>::type OutputShape;
1326 
1327  // Get local-to-global dof index lookup
1328  const unsigned int n_dofs = cast_int<unsigned int>
1329  (this->get_dof_indices(var).size());
1330 
1331  // Get current local coefficients
1332  libmesh_assert_greater (_elem_fixed_subsolutions.size(), var);
1333  const DenseSubVector<Number> & coef = this->get_elem_fixed_solution(var);
1334 
1335  // Get finite element object
1336  FEGenericBase<OutputShape> * fe = nullptr;
1337  this->get_element_fe<OutputShape>( var, fe, this->get_elem_dim() );
1338 
1339  // Build a FE for calculating u(p)
1340  FEGenericBase<OutputShape> * fe_new =
1341  this->build_new_fe( fe, p, tolerance, 2 );
1342 
1343  // Get the values of the shape function derivatives
1344  const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor>> & d2phi = fe_new->get_d2phi();
1345 
1346  hess_u = 0.0;
1347 
1348  for (unsigned int l=0; l != n_dofs; l++)
1349  hess_u.add_scaled(d2phi[l][0], coef(l));
1350 
1351  return;
1352 }
1353 
1354 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
1355 
1356 
1357 
1358 template<typename OutputType>
1359 void FEMContext::interior_rate(unsigned int var, unsigned int qp,
1360  OutputType & u) const
1361 {
1362  this->some_value<OutputType,
1366 }
1367 
1368 template<typename OutputType>
1369 void FEMContext::interior_rate_gradient(unsigned int var, unsigned int qp,
1370  OutputType & dudot) const
1371 {
1372  this->some_gradient<OutputType,
1374  <typename TensorTools::DecrementRank
1375  <OutputType>::type>::type>,
1376  &DiffContext::get_elem_solution_rate>(var, qp, dudot);
1377 }
1378 
1379 template<typename OutputType>
1380 void FEMContext::side_rate(unsigned int var, unsigned int qp,
1381  OutputType & u) const
1382 {
1383  this->some_value<OutputType,
1387 }
1388 
1389 template<typename OutputType>
1390 void FEMContext::interior_accel(unsigned int var, unsigned int qp,
1391  OutputType & u) const
1392 {
1393  this->some_value<OutputType,
1397 }
1398 
1399 
1400 
1401 template<typename OutputType>
1402 void FEMContext::side_accel(unsigned int var, unsigned int qp,
1403  OutputType & u) const
1404 {
1405  this->some_value<OutputType,
1409 }
1410 
1411 
1412 
1414 {
1415  // Update the "time" variable of this context object
1416  this->_update_time_from_system(theta);
1417 
1418  // Handle a moving element if necessary.
1419  if (_mesh_sys)
1420  {
1421  // We assume that the ``default'' state
1422  // of the mesh is its final, theta=1.0
1423  // position, so we don't bother with
1424  // mesh motion in that case.
1425  if (theta != 1.0)
1426  {
1427  // FIXME - ALE is not threadsafe yet!
1428  libmesh_assert_equal_to (libMesh::n_threads(), 1);
1429 
1430  elem_position_set(theta);
1431  }
1432  elem_fe_reinit();
1433  }
1434 }
1435 
1436 
1438 {
1439  // Update the "time" variable of this context object
1440  this->_update_time_from_system(theta);
1441 
1442  // Handle a moving element if necessary
1443  if (_mesh_sys)
1444  {
1445  // FIXME - not threadsafe yet!
1446  elem_position_set(theta);
1447  side_fe_reinit();
1448  }
1449 }
1450 
1451 
1453 {
1454  // Update the "time" variable of this context object
1455  this->_update_time_from_system(theta);
1456 
1457  // Handle a moving element if necessary
1458  if (_mesh_sys)
1459  {
1460  // FIXME - not threadsafe yet!
1461  elem_position_set(theta);
1462  edge_fe_reinit();
1463  }
1464 }
1465 
1466 
1468 {
1469  // Update the "time" variable of this context object
1470  this->_update_time_from_system(theta);
1471 
1472  // We can reuse the Elem FE safely here.
1473  elem_fe_reinit();
1474 }
1475 
1476 
1477 void FEMContext::elem_fe_reinit(const std::vector<Point> * const pts)
1478 {
1479  // Initialize all the interior FE objects on elem.
1480  // Logging of FE::reinit is done in the FE functions
1481  // We only reinit the FE objects for the current element
1482  // dimension
1483  const unsigned char dim = this->get_elem_dim();
1484 
1485  libmesh_assert( !_element_fe[dim].empty() );
1486 
1487  for (const auto & pr : _element_fe[dim])
1488  {
1489  if (this->has_elem())
1490  pr.second->reinit(&(this->get_elem()), pts);
1491  else
1492  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
1493  pr.second->reinit(nullptr);
1494  }
1495 }
1496 
1497 
1499 {
1500  // Initialize all the side FE objects on elem/side.
1501  // Logging of FE::reinit is done in the FE functions
1502  // We only reinit the FE objects for the current element
1503  // dimension
1504  const unsigned char dim = this->get_elem_dim();
1505 
1506  libmesh_assert( !_side_fe[dim].empty() );
1507 
1508  for (auto & pr : _side_fe[dim])
1509  pr.second->reinit(&(this->get_elem()), this->get_side());
1510 }
1511 
1512 
1513 
1515 {
1516  libmesh_assert_equal_to (this->get_elem_dim(), 3);
1517 
1518  // Initialize all the interior FE objects on elem/edge.
1519  // Logging of FE::reinit is done in the FE functions
1520  for (auto & pr : _edge_fe)
1521  pr.second->edge_reinit(&(this->get_elem()), this->get_edge());
1522 }
1523 
1524 
1525 
1527 {
1528  // This is too expensive to call unless we've been asked to move the mesh
1530 
1531  // This will probably break with threading when two contexts are
1532  // operating on elements which share a node
1533  libmesh_assert_equal_to (libMesh::n_threads(), 1);
1534 
1535  // If the coordinate data is in our own system, it's already
1536  // been set up for us
1537  // if (_mesh_sys == this->number())
1538  // {
1539  unsigned int n_nodes = this->get_elem().n_nodes();
1540 
1541 #ifndef NDEBUG
1542  const unsigned char dim = this->get_elem_dim();
1543 
1544  // For simplicity we demand that mesh coordinates be stored
1545  // in a format that allows a direct copy
1547  (this->get_element_fe(this->get_mesh_x_var(), dim)->get_fe_type().family
1548  == FEMap::map_fe_type(this->get_elem()) &&
1549  this->get_element_fe(this->get_mesh_x_var(), dim)->get_fe_type().order.get_order()
1550  == this->get_elem().default_order()));
1552  (this->get_element_fe(this->get_mesh_y_var(), dim)->get_fe_type().family
1553  == FEMap::map_fe_type(this->get_elem()) &&
1554  this->get_element_fe(this->get_mesh_y_var(), dim)->get_fe_type().order.get_order()
1555  == this->get_elem().default_order()));
1557  (this->get_element_fe(this->get_mesh_z_var(), dim)->get_fe_type().family
1558  == FEMap::map_fe_type(this->get_elem()) &&
1559  this->get_element_fe(this->get_mesh_z_var(), dim)->get_fe_type().order.get_order()
1560  == this->get_elem().default_order()));
1561 #endif
1562 
1563  // Get degree of freedom coefficients from point coordinates
1564  if (this->get_mesh_x_var() != libMesh::invalid_uint)
1565  for (unsigned int i=0; i != n_nodes; ++i)
1566  (this->get_elem_solution(this->get_mesh_x_var()))(i) = this->get_elem().point(i)(0);
1567 
1568  if (this->get_mesh_y_var() != libMesh::invalid_uint)
1569  for (unsigned int i=0; i != n_nodes; ++i)
1570  (this->get_elem_solution(this->get_mesh_y_var()))(i) = this->get_elem().point(i)(1);
1571 
1572  if (this->get_mesh_z_var() != libMesh::invalid_uint)
1573  for (unsigned int i=0; i != n_nodes; ++i)
1574  (this->get_elem_solution(this->get_mesh_z_var()))(i) = this->get_elem().point(i)(2);
1575  // }
1576  // FIXME - If the coordinate data is not in our own system, someone
1577  // had better get around to implementing that... - RHS
1578  // else
1579  // {
1580  // libmesh_not_implemented();
1581  // }
1582 }
1583 
1584 
1585 
1587 {
1588  for (auto & m : _element_fe)
1589  for (auto & pr : m)
1590  pr.second->get_fe_map().set_jacobian_tolerance(tol);
1591 
1592  for (auto & m : _side_fe)
1593  for (auto & pr : m)
1594  pr.second->get_fe_map().set_jacobian_tolerance(tol);
1595 
1596  for (auto & pr : _edge_fe)
1597  pr.second->get_fe_map().set_jacobian_tolerance(tol);
1598 }
1599 
1600 
1601 
1602 // We can ignore the theta argument in the current use of this
1603 // function, because elem_subsolutions will already have been set to
1604 // the theta value.
1605 //
1606 // To enable loose mesh movement coupling things will need to change.
1608 {
1609  // This is too expensive to call unless we've been asked to move the mesh
1611 
1612  // This will probably break with threading when two contexts are
1613  // operating on elements which share a node
1614  libmesh_assert_equal_to (libMesh::n_threads(), 1);
1615 
1616  // If the coordinate data is in our own system, it's already
1617  // been set up for us, and we can ignore our input parameter theta
1618  // if (_mesh_sys == this->number())
1619  // {
1620  unsigned int n_nodes = this->get_elem().n_nodes();
1621 
1622 #ifndef NDEBUG
1623  const unsigned char dim = this->get_elem_dim();
1624 
1625  // For simplicity we demand that mesh coordinates be stored
1626  // in a format that allows a direct copy
1628  (this->get_element_fe(this->get_mesh_x_var(), dim)->get_fe_type().family
1629  == FEMap::map_fe_type(this->get_elem()) &&
1630  this->get_elem_solution(this->get_mesh_x_var()).size() == n_nodes));
1632  (this->get_element_fe(this->get_mesh_y_var(), dim)->get_fe_type().family
1633  == FEMap::map_fe_type(this->get_elem()) &&
1634  this->get_elem_solution(this->get_mesh_y_var()).size() == n_nodes));
1636  (this->get_element_fe(this->get_mesh_z_var(), dim)->get_fe_type().family
1637  == FEMap::map_fe_type(this->get_elem()) &&
1638  this->get_elem_solution(this->get_mesh_z_var()).size() == n_nodes));
1639 #endif
1640 
1641  // Set the new point coordinates
1642  if (this->get_mesh_x_var() != libMesh::invalid_uint)
1643  for (unsigned int i=0; i != n_nodes; ++i)
1644  const_cast<Elem &>(this->get_elem()).point(i)(0) =
1645  libmesh_real(this->get_elem_solution(this->get_mesh_x_var())(i));
1646 
1647  if (this->get_mesh_y_var() != libMesh::invalid_uint)
1648  for (unsigned int i=0; i != n_nodes; ++i)
1649  const_cast<Elem &>(this->get_elem()).point(i)(1) =
1650  libmesh_real(this->get_elem_solution(this->get_mesh_y_var())(i));
1651 
1652  if (this->get_mesh_z_var() != libMesh::invalid_uint)
1653  for (unsigned int i=0; i != n_nodes; ++i)
1654  const_cast<Elem &>(this->get_elem()).point(i)(2) =
1655  libmesh_real(this->get_elem_solution(this->get_mesh_z_var())(i));
1656  // }
1657  // FIXME - If the coordinate data is not in our own system, someone
1658  // had better get around to implementing that... - RHS
1659  // else
1660  // {
1661  // libmesh_not_implemented();
1662  // }
1663 }
1664 
1665 
1666 
1667 
1668 
1669 /*
1670  void FEMContext::reinit(const FEMSystem & sys, Elem * e)
1671  {
1672  // Initialize our elem pointer, algebraic objects
1673  this->pre_fe_reinit(e);
1674 
1675  // Moving the mesh may be necessary
1676  // Reinitializing the FE objects is definitely necessary
1677  this->elem_reinit(1.);
1678  }
1679 */
1680 
1681 
1682 
1683 void FEMContext::pre_fe_reinit(const System & sys, const Elem * e)
1684 {
1685  this->set_elem(e);
1686 
1687  if (algebraic_type() == CURRENT ||
1689  {
1690  // Initialize the per-element data for elem.
1691  if (this->has_elem())
1692  sys.get_dof_map().dof_indices (&(this->get_elem()), this->get_dof_indices());
1693  else
1694  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
1695  sys.get_dof_map().dof_indices
1696  (static_cast<Elem*>(nullptr), this->get_dof_indices());
1697  }
1698 #ifdef LIBMESH_ENABLE_AMR
1699  else if (algebraic_type() == OLD ||
1701  {
1702  // Initialize the per-element data for elem.
1703  if (this->has_elem())
1704  sys.get_dof_map().old_dof_indices (&(this->get_elem()), this->get_dof_indices());
1705  else
1706  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
1708  (static_cast<Elem*>(nullptr), this->get_dof_indices());
1709  }
1710 #endif // LIBMESH_ENABLE_AMR
1711 
1712  const unsigned int n_dofs = cast_int<unsigned int>
1713  (this->get_dof_indices().size());
1714  const unsigned int n_qoi = sys.n_qois();
1715 
1716  if (this->algebraic_type() != NONE &&
1717  this->algebraic_type() != DOFS_ONLY &&
1718  this->algebraic_type() != OLD_DOFS_ONLY)
1719  {
1720  // This also resizes elem_solution
1721  if (_custom_solution == nullptr)
1722  sys.current_local_solution->get(this->get_dof_indices(), this->get_elem_solution().get_values());
1723  else
1724  _custom_solution->get(this->get_dof_indices(), this->get_elem_solution().get_values());
1725 
1726  if (sys.use_fixed_solution)
1727  this->get_elem_fixed_solution().resize(n_dofs);
1728 
1729  // Only make space for these if we're using DiffSystem
1730  // This is assuming *only* DiffSystem is using elem_solution_rate/accel
1731  const DifferentiableSystem * diff_system = dynamic_cast<const DifferentiableSystem *>(&sys);
1732  if (diff_system)
1733  {
1734  // Now, we only need these if the solver is unsteady
1735  if (!diff_system->get_time_solver().is_steady())
1736  {
1737  this->get_elem_solution_rate().resize(n_dofs);
1738 
1739  // We only need accel space if the TimeSolver is second order
1740  const UnsteadySolver & time_solver = cast_ref<const UnsteadySolver &>(diff_system->get_time_solver());
1741 
1742  if (time_solver.time_order() >= 2 || !diff_system->get_second_order_vars().empty())
1743  this->get_elem_solution_accel().resize(n_dofs);
1744  }
1745  }
1746 
1747  if (algebraic_type() != OLD)
1748  {
1749  // These resize calls also zero out the residual and jacobian
1750  this->get_elem_residual().resize(n_dofs);
1751  if (this->_have_local_matrices)
1752  this->get_elem_jacobian().resize(n_dofs, n_dofs);
1753 
1754  this->get_qoi_derivatives().resize(n_qoi);
1755  this->_elem_qoi_subderivatives.resize(n_qoi);
1756  for (std::size_t q=0; q != n_qoi; ++q)
1757  (this->get_qoi_derivatives())[q].resize(n_dofs);
1758  }
1759  }
1760 
1761  // Initialize the per-variable data for elem.
1762  {
1763  unsigned int sub_dofs = 0;
1764  for (auto i : make_range(sys.n_vars()))
1765  {
1766  if (algebraic_type() == CURRENT ||
1768  {
1769  if (this->has_elem())
1770  sys.get_dof_map().dof_indices (&(this->get_elem()), this->get_dof_indices(i), i);
1771  else
1772  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
1773  sys.get_dof_map().dof_indices
1774  (static_cast<Elem*>(nullptr), this->get_dof_indices(i), i);
1775  }
1776 #ifdef LIBMESH_ENABLE_AMR
1777  else if (algebraic_type() == OLD ||
1779  {
1780  if (this->has_elem())
1781  sys.get_dof_map().old_dof_indices (&(this->get_elem()), this->get_dof_indices(i), i);
1782  else
1783  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
1785  (static_cast<Elem*>(nullptr), this->get_dof_indices(i), i);
1786  }
1787 #endif // LIBMESH_ENABLE_AMR
1788 
1789  if (this->algebraic_type() != NONE &&
1790  this->algebraic_type() != DOFS_ONLY &&
1791  this->algebraic_type() != OLD_DOFS_ONLY)
1792  {
1793  const unsigned int n_dofs_var = cast_int<unsigned int>
1794  (this->get_dof_indices(i).size());
1795 
1796 
1797  if (!_active_vars ||
1798  std::binary_search(_active_vars->begin(),
1799  _active_vars->end(), i))
1800  {
1801  this->get_elem_solution(i).reposition
1802  (sub_dofs, n_dofs_var);
1803 
1804  // Only make space for these if we're using DiffSystem
1805  // This is assuming *only* DiffSystem is using elem_solution_rate/accel
1806  const DifferentiableSystem * diff_system = dynamic_cast<const DifferentiableSystem *>(&sys);
1807  if (diff_system)
1808  {
1809  // Now, we only need these if the solver is unsteady
1810  if (!diff_system->get_time_solver().is_steady())
1811  {
1812  this->get_elem_solution_rate(i).reposition
1813  (sub_dofs, n_dofs_var);
1814 
1815  // We only need accel space if the TimeSolver is second order
1816  const UnsteadySolver & time_solver = cast_ref<const UnsteadySolver &>(diff_system->get_time_solver());
1817 
1818  if (time_solver.time_order() >= 2 || !diff_system->get_second_order_vars().empty())
1819  this->get_elem_solution_accel(i).reposition
1820  (sub_dofs, n_dofs_var);
1821  }
1822  }
1823 
1824  if (sys.use_fixed_solution)
1825  this->get_elem_fixed_solution(i).reposition
1826  (sub_dofs, n_dofs_var);
1827 
1828  if (algebraic_type() != OLD)
1829  {
1830  this->get_elem_residual(i).reposition
1831  (sub_dofs, n_dofs_var);
1832 
1833  for (std::size_t q=0; q != n_qoi; ++q)
1834  this->get_qoi_derivatives(q,i).reposition
1835  (sub_dofs, n_dofs_var);
1836 
1837  if (this->_have_local_matrices)
1838  {
1839  for (unsigned int j=0; j != i; ++j)
1840  {
1841  const unsigned int n_dofs_var_j =
1842  cast_int<unsigned int>
1843  (this->get_dof_indices(j).size());
1844 
1845  this->get_elem_jacobian(i,j).reposition
1846  (sub_dofs, this->get_elem_residual(j).i_off(),
1847  n_dofs_var, n_dofs_var_j);
1848  this->get_elem_jacobian(j,i).reposition
1849  (this->get_elem_residual(j).i_off(), sub_dofs,
1850  n_dofs_var_j, n_dofs_var);
1851  }
1852  this->get_elem_jacobian(i,i).reposition
1853  (sub_dofs, sub_dofs,
1854  n_dofs_var,
1855  n_dofs_var);
1856  }
1857  }
1858  }
1859 
1860  sub_dofs += n_dofs_var;
1861  }
1862  }
1863 
1864  if (this->algebraic_type() != NONE &&
1865  this->algebraic_type() != DOFS_ONLY &&
1866  this->algebraic_type() != OLD &&
1867  this->algebraic_type() != OLD_DOFS_ONLY)
1868  libmesh_assert_equal_to (sub_dofs, n_dofs);
1869  }
1870 
1871  // Now do the localization for the user requested vectors
1872  if (this->algebraic_type() != NONE &&
1873  this->algebraic_type() != DOFS_ONLY &&
1874  this->algebraic_type() != OLD_DOFS_ONLY)
1875  {
1876  DiffContext::localized_vectors_iterator localized_vec_it = this->_localized_vectors.begin();
1877  const DiffContext::localized_vectors_iterator localized_vec_end = this->_localized_vectors.end();
1878 
1879  for (; localized_vec_it != localized_vec_end; ++localized_vec_it)
1880  {
1881  const NumericVector<Number> & current_localized_vector = *localized_vec_it->first;
1882  DenseVector<Number> & target_vector = localized_vec_it->second.first;
1883 
1884  current_localized_vector.get(this->get_dof_indices(), target_vector.get_values());
1885 
1886  // Initialize the per-variable data for elem.
1887  unsigned int sub_dofs = 0;
1888  auto init_localized_var_data = [this, localized_vec_it, &sub_dofs](unsigned int i)
1889  {
1890  const unsigned int n_dofs_var = cast_int<unsigned int>
1891  (this->get_dof_indices(i).size());
1892 
1893  // This is redundant with earlier initialization, isn't it? - RHS
1894  // sys.get_dof_map().dof_indices (&(this->get_elem()), this->get_dof_indices(i), i);
1895 
1896  localized_vec_it->second.second[i].reposition
1897  (sub_dofs, n_dofs_var);
1898 
1899  sub_dofs += n_dofs_var;
1900  };
1901 
1902  if (_active_vars)
1903  for (auto v : *_active_vars)
1904  init_localized_var_data(v);
1905  else
1906  for (auto v : make_range(sys.n_vars()))
1907  init_localized_var_data(v);
1908 
1909  libmesh_assert_equal_to (sub_dofs, n_dofs);
1910  }
1911  }
1912 }
1913 
1914 void FEMContext::set_elem( const Elem * e )
1915 {
1916  this->_elem = e;
1917 
1918  // If e is nullptr, we assume it's SCALAR and set _elem_dim to 0.
1919  this->_elem_dim =
1920  cast_int<unsigned char>(this->_elem ? this->_elem->dim() : 0);
1921 }
1922 
1924 {
1925  // Update the "time" variable based on the value of theta. For this
1926  // to work, we need to know the value of deltat, a pointer to which is now
1927  // stored by our parent DiffContext class. Note: get_deltat_value() will
1928  // assert in debug mode if the requested pointer is nullptr.
1929  const Real deltat = this->get_deltat_value();
1930 
1931  this->set_time(theta*(this->get_system_time() + deltat) + (1.-theta)*this->get_system_time());
1932 }
1933 
1934 
1935 
1936 template<>
1938 FEMContext::cached_fe( const unsigned int elem_dim,
1939  const FEType fe_type,
1940  const int get_derivative_level ) const
1941 {
1942 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1943  const bool fe_needs_inf =
1944  this->has_elem() && this->get_elem().infinite();
1945 #endif
1946 
1947  if (!_real_fe ||
1948  elem_dim != _real_fe->get_dim() ||
1949  fe_type != _real_fe->get_fe_type() ||
1950  get_derivative_level != _real_fe_derivative_level)
1951  {
1952  _real_fe_derivative_level = get_derivative_level;
1953 
1954  _real_fe =
1955 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1956  fe_needs_inf ?
1957  FEGenericBase<Real>::build_InfFE(elem_dim, fe_type) :
1958 #endif
1959  FEGenericBase<Real>::build(elem_dim, fe_type);
1960  }
1961 
1962 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1963  else if (fe_needs_inf && !_real_fe_is_inf)
1964  _real_fe =
1965  FEGenericBase<Real>::build_InfFE(elem_dim, fe_type);
1966  else if (!fe_needs_inf && _real_fe_is_inf)
1967  _real_fe =
1968  FEGenericBase<Real>::build(elem_dim, fe_type);
1969 
1970  _real_fe_is_inf =
1971  (this->has_elem() && this->get_elem().infinite());
1972 #endif
1973 
1974  return _real_fe.get();
1975 }
1976 
1977 
1978 template<>
1980 FEMContext::cached_fe( const unsigned int elem_dim,
1981  const FEType fe_type,
1982  const int get_derivative_level ) const
1983 {
1984 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1985  const bool fe_needs_inf =
1986  this->has_elem() && this->get_elem().infinite();
1987 #endif
1988 
1989  if (!_real_grad_fe ||
1990  elem_dim != _real_grad_fe->get_dim() ||
1991  fe_type != _real_grad_fe->get_fe_type() ||
1992  get_derivative_level != _real_grad_fe_derivative_level)
1993  {
1994  _real_grad_fe_derivative_level = get_derivative_level;
1995 
1996  _real_grad_fe =
1997 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1998  fe_needs_inf ?
1999  FEGenericBase<RealGradient>::build_InfFE(elem_dim, fe_type) :
2000 #endif
2001  FEGenericBase<RealGradient>::build(elem_dim, fe_type);
2002  }
2003 
2004 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2005  else if (fe_needs_inf && !_real_grad_fe_is_inf)
2006  _real_grad_fe =
2007  FEGenericBase<RealGradient>::build_InfFE(elem_dim, fe_type);
2008  else if (!fe_needs_inf && _real_grad_fe_is_inf)
2009  _real_grad_fe =
2010  FEGenericBase<RealGradient>::build(elem_dim, fe_type);
2011 
2013  (this->has_elem() && this->get_elem().infinite());
2014 #endif
2015 
2016  return _real_grad_fe.get();
2017 }
2018 
2019 
2020 
2021 template<typename OutputShape>
2024  const Point & p,
2025  const Real tolerance,
2026  const int get_derivative_level) const
2027 {
2028  FEType fe_type = fe->get_fe_type();
2029 
2030  // If we don't have an Elem to evaluate on, then the only functions
2031  // we can sensibly evaluate are the scalar dofs which are the same
2032  // everywhere.
2033  libmesh_assert(this->has_elem() || fe_type.family == SCALAR);
2034 
2035 #ifdef LIBMESH_ENABLE_AMR
2036  const int add_p_level = fe->add_p_level_in_reinit();
2037  if ((algebraic_type() == OLD) &&
2038  this->has_elem())
2039  {
2040  if (this->get_elem().p_refinement_flag() == Elem::JUST_REFINED)
2041  fe_type.order -= add_p_level;
2042  else if (this->get_elem().p_refinement_flag() == Elem::JUST_COARSENED)
2043  fe_type.order += add_p_level;
2044  }
2045 #endif // LIBMESH_ENABLE_AMR
2046 
2047  const unsigned int elem_dim = this->has_elem() ? this->get_elem().dim() : 0;
2048 
2049  FEGenericBase<OutputShape>* fe_new =
2050  cached_fe<OutputShape>(elem_dim, fe_type, get_derivative_level);
2051 #ifdef LIBMESH_ENABLE_AMR
2052  fe_new->add_p_level_in_reinit(add_p_level);
2053 #endif // LIBMESH_ENABLE_AMR
2054 
2055  // Map the physical co-ordinates to the master co-ordinates using the inverse_map from fe_interface.h
2056  // Build a vector of point co-ordinates to send to reinit
2057  Point master_point = this->has_elem() ?
2058  FEMap::inverse_map (elem_dim, &this->get_elem(), p, tolerance) :
2059  Point(0);
2060 
2061  std::vector<Point> coor(1, master_point);
2062 
2063  switch (get_derivative_level)
2064  {
2065  case -1:
2066  fe_new->get_phi();
2067  fe_new->get_dphi();
2068 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2069  fe_new->get_d2phi();
2070 #endif
2071  fe_new->get_curl_phi();
2072  break;
2073  case 0:
2074  fe_new->get_phi();
2075  break;
2076  case 1:
2077  fe_new->get_dphi();
2078  break;
2079  case 2:
2080 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2081  fe_new->get_d2phi();
2082 #else
2083  // here a different configuration is required.
2084  libmesh_not_implemented();
2085 #endif
2086  break;
2087  case 3:
2088  fe_new->get_curl_phi();
2089  break;
2090  default:
2091  libmesh_error();
2092  }
2093 
2094  // Reinitialize the element and compute the shape function values at coor
2095  if (this->has_elem())
2096  fe_new->reinit (&this->get_elem(), &coor);
2097  else
2098  // If !this->has_elem(), then we assume we are dealing with a SCALAR variable
2099  fe_new->reinit (nullptr, &coor);
2100 
2101  return fe_new;
2102 }
2103 
2104 
2105 
2106 
2107 
2108 // Instantiate member function templates
2109 template LIBMESH_EXPORT void FEMContext::interior_value<Number>(unsigned int, unsigned int, Number &) const;
2110 template LIBMESH_EXPORT void FEMContext::interior_values<Number>(unsigned int, const NumericVector<Number> &,
2111  std::vector<Number> &) const;
2112 template LIBMESH_EXPORT void FEMContext::interior_value<Gradient>(unsigned int, unsigned int, Gradient &) const;
2113 template LIBMESH_EXPORT void FEMContext::interior_values<Gradient>(unsigned int, const NumericVector<Number> &,
2114  std::vector<Gradient> &) const;
2115 
2116 template LIBMESH_EXPORT void FEMContext::interior_gradient<Gradient>(unsigned int, unsigned int, Gradient &) const;
2117 template LIBMESH_EXPORT void FEMContext::interior_gradients<Gradient>(unsigned int, const NumericVector<Number> &,
2118  std::vector<Gradient> &) const;
2119 template LIBMESH_EXPORT void FEMContext::interior_gradient<Tensor>(unsigned int, unsigned int, Tensor &) const;
2120 template LIBMESH_EXPORT void FEMContext::interior_gradients<Tensor>(unsigned int, const NumericVector<Number> &,
2121  std::vector<Tensor> &) const;
2122 
2123 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2124 template LIBMESH_EXPORT void FEMContext::interior_hessian<Tensor>(unsigned int, unsigned int, Tensor &) const;
2125 template LIBMESH_EXPORT void FEMContext::interior_hessians<Tensor>(unsigned int, const NumericVector<Number> &,
2126  std::vector<Tensor> &) const;
2127 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2128 //template LIBMESH_EXPORT void FEMContext::interior_hessian<??>(unsigned int, unsigned int, ??&) const;
2129 //template LIBMESH_EXPORT void FEMContext::interior_hessians<??>(unsigned int, const NumericVector<Number> &,
2130 // std::vector<??> &) const;
2131 #endif
2132 
2133 template LIBMESH_EXPORT void FEMContext::interior_curl<Gradient>(unsigned int, unsigned int, Gradient &) const;
2134 
2135 template LIBMESH_EXPORT void FEMContext::interior_div<Number>(unsigned int, unsigned int, Number &) const;
2136 
2137 template LIBMESH_EXPORT void FEMContext::side_value<Number>(unsigned int, unsigned int, Number &) const;
2138 template LIBMESH_EXPORT void FEMContext::side_value<Gradient>(unsigned int, unsigned int, Gradient &) const;
2139 template LIBMESH_EXPORT void FEMContext::side_values<Number>(unsigned int, const NumericVector<Number> &,
2140  std::vector<Number> &) const;
2141 template LIBMESH_EXPORT void FEMContext::side_values<Gradient>(unsigned int, const NumericVector<Number> &,
2142  std::vector<Gradient> &) const;
2143 
2144 template LIBMESH_EXPORT void FEMContext::side_gradient<Gradient>(unsigned int, unsigned int, Gradient &) const;
2145 template LIBMESH_EXPORT void FEMContext::side_gradients<Gradient>(unsigned int, const NumericVector<Number> &,
2146  std::vector<Gradient> &) const;
2147 template LIBMESH_EXPORT void FEMContext::side_gradient<Tensor>(unsigned int, unsigned int, Tensor &) const;
2148 template LIBMESH_EXPORT void FEMContext::side_gradients<Tensor>(unsigned int, const NumericVector<Number> &,
2149  std::vector<Tensor> &) const;
2150 
2151 
2152 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2153 template LIBMESH_EXPORT void FEMContext::side_hessian<Tensor>(unsigned int, unsigned int, Tensor &) const;
2154 template LIBMESH_EXPORT void FEMContext::side_hessians<Tensor>(unsigned int, const NumericVector<Number> &,
2155  std::vector<Tensor> &) const;
2156 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2157 //template LIBMESH_EXPORT void FEMContext::side_hessian<??>(unsigned int, unsigned int,
2158 // ??&) const;
2159 //template LIBMESH_EXPORT void FEMContext::side_hessians<??>(unsigned int, const NumericVector<Number> &,
2160 // std::vector<??> &) const;
2161 #endif
2162 
2163 template LIBMESH_EXPORT void FEMContext::point_value<Number>(unsigned int, const Point &, Number &, const Real) const;
2164 template LIBMESH_EXPORT void FEMContext::point_value<Gradient>(unsigned int, const Point &, Gradient &, const Real) const;
2165 
2166 template LIBMESH_EXPORT void FEMContext::point_gradient<Gradient>(unsigned int, const Point &, Gradient &, const Real) const;
2167 template LIBMESH_EXPORT void FEMContext::point_gradient<Tensor>(unsigned int, const Point &, Tensor &, const Real) const;
2168 
2169 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2170 template LIBMESH_EXPORT void FEMContext::point_hessian<Tensor>(unsigned int, const Point &, Tensor &, const Real) const;
2171 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2172 //template LIBMESH_EXPORT void FEMContext::point_hessian<??>(unsigned int, const Point &, ??&) const;
2173 #endif
2174 
2175 template LIBMESH_EXPORT void FEMContext::point_curl<Gradient>(unsigned int, const Point &, Gradient &, const Real) const;
2176 
2177 template LIBMESH_EXPORT void FEMContext::fixed_interior_value<Number>(unsigned int, unsigned int, Number &) const;
2178 template LIBMESH_EXPORT void FEMContext::fixed_interior_value<Gradient>(unsigned int, unsigned int, Gradient &) const;
2179 
2180 template LIBMESH_EXPORT void FEMContext::fixed_interior_gradient<Gradient>(unsigned int, unsigned int, Gradient &) const;
2181 template LIBMESH_EXPORT void FEMContext::fixed_interior_gradient<Tensor>(unsigned int, unsigned int, Tensor &) const;
2182 
2183 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2184 template LIBMESH_EXPORT void FEMContext::fixed_interior_hessian<Tensor>(unsigned int, unsigned int, Tensor &) const;
2185 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2186 //template LIBMESH_EXPORT void FEMContext::fixed_interior_hessian<??>(unsigned int, unsigned int, ??&) const;
2187 #endif
2188 
2189 template LIBMESH_EXPORT void FEMContext::fixed_side_value<Number>(unsigned int, unsigned int, Number &) const;
2190 template LIBMESH_EXPORT void FEMContext::fixed_side_value<Gradient>(unsigned int, unsigned int, Gradient &) const;
2191 
2192 template LIBMESH_EXPORT void FEMContext::fixed_side_gradient<Gradient>(unsigned int, unsigned int, Gradient &) const;
2193 template LIBMESH_EXPORT void FEMContext::fixed_side_gradient<Tensor>(unsigned int, unsigned int, Tensor &) const;
2194 
2195 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2196 template LIBMESH_EXPORT void FEMContext::fixed_side_hessian<Tensor>(unsigned int, unsigned int, Tensor &) const;
2197 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2198 //template LIBMESH_EXPORT void FEMContext::fixed_side_hessian<??>(unsigned int, unsigned int, ??&) const;
2199 #endif
2200 
2201 template LIBMESH_EXPORT void FEMContext::fixed_point_value<Number>(unsigned int, const Point &, Number &, const Real) const;
2202 template LIBMESH_EXPORT void FEMContext::fixed_point_value<Gradient>(unsigned int, const Point &, Gradient &, const Real) const;
2203 
2204 template LIBMESH_EXPORT void FEMContext::fixed_point_gradient<Gradient>(unsigned int, const Point &, Gradient &, const Real) const;
2205 template LIBMESH_EXPORT void FEMContext::fixed_point_gradient<Tensor>(unsigned int, const Point &, Tensor &, const Real) const;
2206 
2207 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2208 template LIBMESH_EXPORT void FEMContext::fixed_point_hessian<Tensor>(unsigned int, const Point &, Tensor &, const Real) const;
2209 //FIXME: Not everything is implemented yet for second derivatives of RealGradients
2210 //template LIBMESH_EXPORT void FEMContext::fixed_point_hessian<??>(unsigned int, const Point &, ??&) const;
2211 #endif
2212 
2213 template LIBMESH_EXPORT void FEMContext::interior_rate<Number>(unsigned int, unsigned int, Number &) const;
2214 template LIBMESH_EXPORT void FEMContext::interior_rate<Gradient>(unsigned int, unsigned int, Gradient &) const;
2215 
2216 template LIBMESH_EXPORT void FEMContext::interior_rate_gradient<Gradient>(unsigned int, unsigned int, Gradient &) const;
2217 template LIBMESH_EXPORT void FEMContext::interior_rate_gradient<Tensor>(unsigned int, unsigned int, Tensor &) const;
2218 
2219 template LIBMESH_EXPORT void FEMContext::side_rate<Number>(unsigned int, unsigned int, Number &) const;
2220 template LIBMESH_EXPORT void FEMContext::side_rate<Gradient>(unsigned int, unsigned int, Gradient &) const;
2221 
2222 template LIBMESH_EXPORT void FEMContext::interior_accel<Number>(unsigned int, unsigned int, Number &) const;
2223 template LIBMESH_EXPORT void FEMContext::interior_accel<Gradient>(unsigned int, unsigned int, Gradient &) const;
2224 
2225 template LIBMESH_EXPORT void FEMContext::side_accel<Number>(unsigned int, unsigned int, Number &) const;
2226 template LIBMESH_EXPORT void FEMContext::side_accel<Gradient>(unsigned int, unsigned int, Gradient &) const;
2227 
2228 template LIBMESH_EXPORT FEGenericBase<Real> *
2230  const Point &,
2231  const Real,
2232  const int) const;
2233 
2234 template LIBMESH_EXPORT FEGenericBase<RealGradient> *
2236  const Point &,
2237  const Real,
2238  const int) const;
2239 
2240 } // namespace libMesh
T libmesh_real(T a)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
void interior_curl(unsigned int var, unsigned int qp, OutputType &curl_u) const
Definition: fem_context.C:598
FEFamily family
The type of finite element.
Definition: fe_type.h:221
unsigned char get_edge() const
Accessor for current edge of Elem object.
Definition: fem_context.h:928
virtual void nonlocal_reinit(Real theta) override
Gives derived classes the opportunity to reinitialize data needed for nonlocal calculations at a new ...
Definition: fem_context.C:1467
FEGenericBase< OutputShape > * cached_fe(const unsigned int elem_dim, const FEType fe_type, const int get_derivative_level) const
virtual_for_inffe const std::vector< std::vector< OutputDivergence > > & get_div_phi() const
Definition: fe_base.h:261
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
Number fixed_side_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1135
Number side_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:661
Tensor fixed_point_hessian(unsigned int var, const Point &p) const
Definition: fem_context.C:1306
Number interior_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:412
unsigned int n_threads()
Definition: libmesh_base.h:96
void elem_position_set(Real theta)
Uses the coordinate data specified by mesh_*_position configuration to set the geometry of elem to th...
Definition: fem_context.h:1270
std::vector< DenseSubVector< Number > > _elem_fixed_subsolutions
Definition: diff_context.h:605
This class provides all data required for a physics package (e.g.
Definition: diff_context.h:55
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...
Definition: fem_context.h:317
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1683
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
unsigned int get_mesh_x_var() const
Accessor for x-variable of moving mesh System.
Definition: fem_context.h:860
std::unique_ptr< const std::vector< unsigned int > > _active_vars
Variables on which to enable calculations, or nullptr if all variables in the System are to be enable...
Definition: fem_context.h:1054
const NumericVector< Number > * _custom_solution
Data with which to do algebra reinitialization.
Definition: fem_context.h:1074
void set_elem(const Elem *e)
Helper function to promote accessor usage.
Definition: fem_context.C:1914
std::unique_ptr< FEGenericBase< RealGradient > > _real_grad_fe
Definition: fem_context.h:1077
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
Access multiple components at once.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2184
const DenseVector< Number > & get_elem_fixed_solution() const
Accessor for element fixed solution.
Definition: diff_context.h:210
const DenseVector< Number > & get_elem_solution_rate() const
Accessor for element solution rate of change w.r.t.
Definition: diff_context.h:144
unsigned char get_elem_dim() const
Definition: fem_context.h:944
const Elem & get_elem() const
Accessor for current Elem object.
Definition: fem_context.h:908
unsigned int dim
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
Definition: fe_map.C:1628
FEMContext(const System &sys, const std::vector< unsigned int > *active_vars=nullptr, bool allocate_local_matrices=true)
Constructor.
Definition: fem_context.C:39
unsigned int n_qois() const
Number of currently active quantities of interest.
Definition: system.h:2608
void side_hessians(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &d2u_vals) const
Fills a vector of hessians of the _system_vector at the all the quadrature points on the current elem...
Definition: fem_context.C:831
void interior_accel(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1390
TensorTools::MakeReal< OutputType >::type value_shape
Definition: fem_context.h:1117
const DenseSubVector< Number > &(DiffContext::* diff_subsolution_getter)(unsigned int) const
Helper typedef to simplify refactoring.
Definition: fem_context.h:1103
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:396
void interior_gradients(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &interior_gradients_vector) const
Fills a vector with the gradient of the solution variable var at all the quadrature points in the cur...
Definition: fem_context.C:494
std::vector< T > & get_values()
Definition: dense_vector.h:278
virtual void elem_edge_reinit(Real theta) override
Resets the current time in the context.
Definition: fem_context.C:1452
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:215
int _extra_quadrature_order
The extra quadrature order for this context.
Definition: fem_context.h:1238
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
void should_p_refine(unsigned int g, bool p_refine)
Describe whether the given variable group should be p-refined.
Definition: dof_map.h:2496
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
std::vector< std::vector< DenseSubVector< Number > > > _elem_qoi_subderivatives
Definition: diff_context.h:627
virtual bool is_steady() const =0
Is this effectively a steady-state solver?
void elem_position_get()
Uses the geometry of elem to set the coordinate data specified by mesh_*_position configuration...
Definition: fem_context.C:1526
The libMesh namespace provides an interface to certain functionality in the library.
void interior_values(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &interior_values_vector) const
Fills a vector of values of the _system_vector at the all the quadrature points in the current elemen...
Definition: fem_context.C:432
bool has_side_boundary_id(boundary_id_type id) const
Reports if the boundary id is found on the current side.
Definition: fem_context.C:298
void use_default_quadrature_rules(int extra_quadrature_order=0)
Use quadrature rules designed to over-integrate a mass matrix, plus extra_quadrature_order.
Definition: fem_context.C:155
virtual ~FEMContext()
Destructor.
Definition: fem_context.C:292
void side_boundary_ids(std::vector< boundary_id_type > &vec_to_fill) const
As above, but fills in the std::set provided by the user.
Definition: fem_context.C:305
unsigned char get_side() const
Accessor for current side of Elem object.
Definition: fem_context.h:922
Number point_value(unsigned int var, const Point &p) const
Definition: fem_context.C:874
std::vector< std::map< FEType, std::unique_ptr< FEAbstract > > > _element_fe
Finite element objects for each variable&#39;s interior, sides and edges.
Definition: fem_context.h:1168
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
Definition: fem_context.C:1477
const bool _have_local_matrices
Whether we have local matrices allocated/initialized.
Definition: diff_context.h:576
std::unique_ptr< FEGenericBase< Real > > _real_fe
Definition: fem_context.h:1076
Number fixed_interior_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1059
Tnew cast_int(Told oldvar)
void interior_rate_gradient(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1369
Defines a dense subvector for use in finite element computations.
FEType get_fe_type() const
Definition: fe_abstract.h:520
This class provides a specific system class.
Definition: diff_system.h:54
Tensor fixed_side_hessian(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1184
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:34
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition: fe_base.h:230
std::set< unsigned char > _elem_dims
Cached dimensions of elements in the mesh, plus dimension 0 if SCALAR variables are in use...
Definition: fem_context.h:1208
Gradient interior_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:467
void point_curl(unsigned int var, const Point &p, OutputType &curl_u, const Real tolerance=TOLERANCE) const
Definition: fem_context.C:1023
const dof_id_type n_nodes
Definition: tecplot_io.C:67
virtual unsigned int time_order() const =0
const std::set< unsigned int > & get_second_order_vars() const
Definition: diff_physics.h:519
const DenseVector< Number > & get_elem_solution() const
Accessor for element solution.
Definition: diff_context.h:112
int8_t boundary_id_type
Definition: id_types.h:51
unsigned char _elem_dim
Cached dimension of this->_elem.
Definition: fem_context.h:1202
void side_gradients(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &side_gradients_vector) const
Fills a vector with the gradient of the solution variable var at all the quadrature points on the cur...
Definition: fem_context.C:764
Tensor side_hessian(unsigned int var, unsigned int qp) const
Definition: fem_context.C:802
virtual void side_fe_reinit()
Reinitializes side FE objects on the current geometric element.
Definition: fem_context.C:1498
std::map< FEType, std::unique_ptr< FEAbstract > > _edge_fe
Definition: fem_context.h:1170
const System & get_system() const
Accessor for associated system.
Definition: diff_context.h:106
void _update_time_from_system(Real theta)
Update the time in the context object for the given value of theta, based on the values of "time" and...
Definition: fem_context.C:1923
virtual unsigned int n_nodes() const =0
void init_internal_data(const System &sys)
Helper function used in constructors to set up internal data.
Definition: fem_context.C:198
Gradient fixed_point_gradient(unsigned int var, const Point &p) const
Definition: fem_context.C:1255
bool use_fixed_solution
A boolean to be set to true by systems using elem_fixed_solution, for optional use by e...
Definition: system.h:1560
void side_accel(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1402
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
void set_jacobian_tolerance(Real tol)
Calls set_jacobian_tolerance() on all the FE objects controlled by this class.
Definition: fem_context.C:1586
System * _mesh_sys
System from which to acquire moving mesh information.
Definition: fem_context.h:1059
void interior_hessians(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &d2u_vals) const
Fills a vector of hessians of the _system_vector at the all the quadrature points in the current elem...
Definition: fem_context.C:556
void some_value(unsigned int var, unsigned int qp, OutputType &u) const
Helper function to reduce some code duplication in the *interior_value methods.
Definition: fem_context.C:315
void some_hessian(unsigned int var, unsigned int qp, OutputType &u) const
Helper function to reduce some code duplication in the *interior_hessian methods. ...
Definition: fem_context.C:382
FEType find_hardest_fe_type()
Helper function for creating quadrature rules.
Definition: fem_context.C:86
void add_p_level_in_reinit(bool value)
Indicate whether to add p-refinement levels in init/reinit methods.
Definition: fe_abstract.h:631
Tensor interior_hessian(unsigned int var, unsigned int qp) const
Definition: fem_context.C:532
const std::vector< unsigned int > * active_vars() const
Return a pointer to the vector of active variables being computed for, or a null pointer if all varia...
Definition: fem_context.h:1034
Tensor point_hessian(unsigned int var, const Point &p) const
Definition: fem_context.C:972
Gradient fixed_interior_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1082
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
libmesh_assert(ctx)
void use_unweighted_quadrature_rules(int extra_quadrature_order=0)
Use quadrature rules designed to exactly integrate unweighted undistorted basis functions, plus extra_quadrature_order.
Definition: fem_context.C:177
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
This is at the core of this class.
void side_values(unsigned int var, const NumericVector< Number > &_system_vector, std::vector< OutputType > &side_values_vector) const
Fills a vector of values of the _system_vector at the all the quadrature points on the current elemen...
Definition: fem_context.C:684
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
Definition: diff_context.h:363
const BoundaryInfo & _boundary_info
Saved reference to BoundaryInfo on the mesh for this System.
Definition: fem_context.h:1187
void set_time(Real time_in)
Set the time for which the current nonlinear_solution is defined.
Definition: diff_context.h:423
std::vector< std::vector< FEAbstract * > > _element_fe_var
Pointers to the same finite element objects, but indexed by variable number.
Definition: fem_context.h:1179
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
Definition: fe_base.h:319
std::map< const NumericVector< Number > *, std::pair< DenseVector< Number >, std::vector< DenseSubVector< Number > > > >::iterator localized_vectors_iterator
Typedef for the localized_vectors iterator.
Definition: diff_context.h:540
std::map< const NumericVector< Number > *, std::pair< DenseVector< Number >, std::vector< DenseSubVector< Number > > > > _localized_vectors
Contains pointers to vectors the user has asked to be localized, keyed with pairs of element localize...
Definition: diff_context.h:571
int _real_grad_fe_derivative_level
Definition: fem_context.h:1079
virtual void elem_side_reinit(Real theta) override
Resets the current time in the context.
Definition: fem_context.C:1437
DenseSubVector< Number > & get_localized_subvector(const NumericVector< Number > &localized_vector, unsigned int var)
Return a reference to DenseSubVector localization of localized_vector at variable var contained in th...
Definition: diff_context.C:154
Real get_system_time() const
Accessor for the time variable stored in the system class.
Definition: diff_context.h:411
Number fixed_point_value(unsigned int var, const Point &p) const
Definition: fem_context.C:1209
virtual void edge_fe_reinit()
Reinitializes edge FE objects on the current geometric element.
Definition: fem_context.C:1514
std::vector< DenseSubVector< Number > > _elem_subsolutions
Definition: diff_context.h:583
std::vector< FEAbstract * > _edge_fe_var
Definition: fem_context.h:1181
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:242
This is a generic class that defines a solver to handle time integration of DifferentiableSystems.
std::vector< std::unique_ptr< QBase > > _side_qrule
Quadrature rules for element sides The FEM context will try to find a quadrature rule that correctly ...
Definition: fem_context.h:1224
std::vector< std::map< FEType, std::unique_ptr< FEAbstract > > > _side_fe
Definition: fem_context.h:1169
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2495
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< std::unique_ptr< QBase > > _element_qrule
Quadrature rule for element interior.
Definition: fem_context.h:1216
std::unique_ptr< QBase > unweighted_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:53
unsigned char side
Current side for side_* to examine.
Definition: fem_context.h:1013
virtual unsigned short dim() const =0
const DenseVector< Number > & get_elem_solution_accel() const
Accessor for element solution accel of change w.r.t.
Definition: diff_context.h:177
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Definition: fe_abstract.C:78
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
std::unique_ptr< QBase > _edge_qrule
Quadrature rules for element edges.
Definition: fem_context.h:1233
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1602
Helper nested class for C++03-compatible "template typedef".
Definition: fem_context.h:1110
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...
Definition: fem_context.h:277
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
Gradient fixed_side_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1159
unsigned int get_mesh_y_var() const
Accessor for y-variable of moving mesh System.
Definition: fem_context.h:874
AlgebraicType algebraic_type() const
Definition: fem_context.h:992
FEGenericBase< OutputShape > * build_new_fe(const FEGenericBase< OutputShape > *fe, const Point &p, const Real tolerance=TOLERANCE, const int get_derivative_level=-1) const
Helper function to reduce some code duplication in the *_point_* methods.
Definition: fem_context.C:2023
void interior_div(unsigned int var, unsigned int qp, OutputType &div_u) const
Definition: fem_context.C:629
virtual bool infinite() const =0
void some_gradient(unsigned int var, unsigned int qp, OutputType &u) const
Helper function to reduce some code duplication in the *interior_gradient methods.
Definition: fem_context.C:349
std::vector< std::vector< FEAbstract * > > _side_fe_var
Definition: fem_context.h:1180
unsigned int n_vars() const
Definition: system.h:2417
Gradient point_gradient(unsigned int var, const Point &p) const
Definition: fem_context.C:920
const Elem * _elem
Current element for element_* to examine.
Definition: fem_context.h:1192
void attach_quadrature_rules()
Helper function for attaching quadrature rules.
Definition: fem_context.C:127
void _do_elem_position_set(Real theta)
Uses the coordinate data specified by mesh_*_position configuration to set the geometry of elem to th...
Definition: fem_context.C:1607
virtual Order default_order() const =0
const std::vector< DenseVector< Number > > & get_qoi_derivatives() const
Const accessor for QoI derivatives.
Definition: diff_context.h:329
bool has_elem() const
Test for current Elem object.
Definition: fem_context.h:902
Gradient side_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:719
const DofMap & get_dof_map() const
Definition: system.h:2361
void interior_rate(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1359
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
const Point & point(const unsigned int i) const
Definition: elem.h:2422
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
void side_rate(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1380
This class forms the foundation from which generic finite elements may be derived.
virtual void elem_reinit(Real theta) override
Resets the current time in the context.
Definition: fem_context.C:1413
unsigned int get_mesh_z_var() const
Accessor for z-variable of moving mesh System.
Definition: fem_context.h:888
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
void old_dof_indices(const Elem &elem, unsigned int n, std::vector< dof_id_type > &di, const unsigned int vn) const
Appends to the vector di the old global degree of freedom indices for elem.node_ref(n), for one variable vn.
Definition: dof_map.C:2438
virtual_for_inffe const std::vector< std::vector< OutputShape > > & get_curl_phi() const
Definition: fe_base.h:252
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207
TimeSolver & get_time_solver()
Definition: diff_system.h:456
static FEFamily map_fe_type(const Elem &elem)
Definition: fe_map.C:46
Tensor fixed_interior_hessian(unsigned int var, unsigned int qp) const
Definition: fem_context.C:1109