https://mooseframework.inl.gov
AuxiliarySystem.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "AuxiliarySystem.h"
11 #include "FEProblem.h"
12 #include "Factory.h"
13 #include "AuxKernel.h"
14 #include "AuxScalarKernel.h"
15 #include "MaterialData.h"
16 #include "Assembly.h"
17 #include "GeometricSearchData.h"
23 #include "Parser.h"
24 #include "TimeIntegrator.h"
25 #include "Conversion.h"
26 
27 #include "libmesh/quadrature_gauss.h"
28 #include "libmesh/node_range.h"
29 #include "libmesh/numeric_vector.h"
30 #include "libmesh/default_coupling.h"
31 #include "libmesh/string_to_enum.h"
32 #include "libmesh/fe_interface.h"
33 
34 // C++
35 #include <cstring> // for "Jacobian" exception test
36 
37 using namespace libMesh;
38 
39 // AuxiliarySystem ////////
40 
41 AuxiliarySystem::AuxiliarySystem(FEProblemBase & subproblem, const std::string & name)
42  : SystemBase(subproblem, subproblem, name, Moose::VAR_AUXILIARY),
43  PerfGraphInterface(subproblem.getMooseApp().perfGraph(), "AuxiliarySystem"),
44  _sys(subproblem.es().add_system<System>(name)),
45  _current_solution(_sys.current_local_solution.get()),
46  _aux_scalar_storage(_app.getExecuteOnEnum()),
47  _nodal_aux_storage(_app.getExecuteOnEnum()),
48  _mortar_nodal_aux_storage(_app.getExecuteOnEnum()),
49  _elemental_aux_storage(_app.getExecuteOnEnum()),
50  _nodal_vec_aux_storage(_app.getExecuteOnEnum()),
51  _elemental_vec_aux_storage(_app.getExecuteOnEnum()),
52  _nodal_array_aux_storage(_app.getExecuteOnEnum()),
53  _elemental_array_aux_storage(_app.getExecuteOnEnum())
54 #ifdef MOOSE_KOKKOS_ENABLED
55  ,
56  _kokkos_nodal_aux_storage(_app.getExecuteOnEnum()),
57  _kokkos_elemental_aux_storage(_app.getExecuteOnEnum())
58 #endif
59 {
60  _nodal_vars.resize(libMesh::n_threads());
61  _elem_vars.resize(libMesh::n_threads());
62 
64  {
65  auto & dof_map = _sys.get_dof_map();
66  dof_map.remove_algebraic_ghosting_functor(dof_map.default_algebraic_ghosting());
67  dof_map.set_implicit_neighbor_dofs(false);
68  }
69 }
70 
72 
73 void
75 {
76  TIME_SECTION("initialSetup", 3, "Initializing Auxiliary System");
77 
79 
80  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
81  {
84 
85  _nodal_aux_storage.sort(tid);
86  _nodal_aux_storage.initialSetup(tid);
87 
88  _mortar_nodal_aux_storage.sort(tid);
89  _mortar_nodal_aux_storage.initialSetup(tid);
90 
91  _nodal_vec_aux_storage.sort(tid);
92  _nodal_vec_aux_storage.initialSetup(tid);
93 
94  _nodal_array_aux_storage.sort(tid);
95  _nodal_array_aux_storage.initialSetup(tid);
96 
97  _elemental_aux_storage.sort(tid);
98  _elemental_aux_storage.initialSetup(tid);
99 
100  _elemental_vec_aux_storage.sort(tid);
101  _elemental_vec_aux_storage.initialSetup(tid);
102 
104  _elemental_array_aux_storage.initialSetup(tid);
105  }
106 
107 #ifdef MOOSE_KOKKOS_ENABLED
108  _kokkos_nodal_aux_storage.sort(/*tid=*/0);
110 
113 #endif
114 }
115 
116 void
118 {
120 
121  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
122  {
124  _nodal_aux_storage.timestepSetup(tid);
125  _mortar_nodal_aux_storage.timestepSetup(tid);
126  _nodal_vec_aux_storage.timestepSetup(tid);
127  _nodal_array_aux_storage.timestepSetup(tid);
128  _elemental_aux_storage.timestepSetup(tid);
129  _elemental_vec_aux_storage.timestepSetup(tid);
130  _elemental_array_aux_storage.timestepSetup(tid);
131  }
132 
133 #ifdef MOOSE_KOKKOS_ENABLED
136 #endif
137 }
138 
139 void
141 {
142  SystemBase::customSetup(exec_type);
143 
144  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
145  {
146  _aux_scalar_storage.customSetup(exec_type, tid);
147  _nodal_aux_storage.customSetup(exec_type, tid);
148  _mortar_nodal_aux_storage.customSetup(exec_type, tid);
149  _nodal_vec_aux_storage.customSetup(exec_type, tid);
150  _nodal_array_aux_storage.customSetup(exec_type, tid);
151  _elemental_aux_storage.customSetup(exec_type, tid);
152  _elemental_vec_aux_storage.customSetup(exec_type, tid);
153  _elemental_array_aux_storage.customSetup(exec_type, tid);
154  }
155 
156 #ifdef MOOSE_KOKKOS_ENABLED
157  _kokkos_nodal_aux_storage.customSetup(exec_type, /*tid=*/0);
158  _kokkos_elemental_aux_storage.customSetup(exec_type, /*tid=*/0);
159 #endif
160 }
161 
162 void
164 {
166 
167  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
168  {
170  _nodal_aux_storage.subdomainSetup(tid);
171  _mortar_nodal_aux_storage.subdomainSetup(tid);
172  _nodal_vec_aux_storage.subdomainSetup(tid);
173  _nodal_array_aux_storage.subdomainSetup(tid);
174  _elemental_aux_storage.subdomainSetup(tid);
175  _elemental_vec_aux_storage.subdomainSetup(tid);
176  _elemental_array_aux_storage.subdomainSetup(tid);
177  }
178 }
179 
180 void
182 {
184 
185  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
186  {
188  _nodal_aux_storage.jacobianSetup(tid);
189  _mortar_nodal_aux_storage.jacobianSetup(tid);
190  _nodal_vec_aux_storage.jacobianSetup(tid);
191  _nodal_array_aux_storage.jacobianSetup(tid);
192  _elemental_aux_storage.jacobianSetup(tid);
193  _elemental_vec_aux_storage.jacobianSetup(tid);
194  _elemental_array_aux_storage.jacobianSetup(tid);
195  }
196 
197 #ifdef MOOSE_KOKKOS_ENABLED
200 #endif
201 }
202 
203 void
205 {
207 
208  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
209  {
211  _nodal_aux_storage.residualSetup(tid);
212  _mortar_nodal_aux_storage.residualSetup(tid);
213  _nodal_vec_aux_storage.residualSetup(tid);
214  _nodal_array_aux_storage.residualSetup(tid);
215  _elemental_aux_storage.residualSetup(tid);
216  _elemental_vec_aux_storage.residualSetup(tid);
217  _elemental_array_aux_storage.residualSetup(tid);
218  }
219 
220 #ifdef MOOSE_KOKKOS_ENABLED
223 #endif
224 }
225 
226 void
228 {
230  _nodal_aux_storage.updateActive(tid);
231  _mortar_nodal_aux_storage.updateActive(tid);
232  _nodal_vec_aux_storage.updateActive(tid);
233  _nodal_array_aux_storage.updateActive(tid);
234  _elemental_aux_storage.updateActive(tid);
235  _elemental_vec_aux_storage.updateActive(tid);
236  _elemental_array_aux_storage.updateActive(tid);
237 
238 #ifdef MOOSE_KOKKOS_ENABLED
239  if (tid == 0)
240  {
243  }
244 #endif
245 }
246 
247 void
248 AuxiliarySystem::addVariable(const std::string & var_type,
249  const std::string & name,
250  InputParameters & parameters)
251 {
252  SystemBase::addVariable(var_type, name, parameters);
253 
254  auto fe_type = FEType(Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")),
255  Utility::string_to_enum<FEFamily>(parameters.get<MooseEnum>("family")));
256 
257  if (var_type == "MooseVariableScalar")
258  return;
259 
260  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
261  {
262  if (FEInterface::field_type(fe_type) == TYPE_VECTOR)
263  {
264  auto * var = _vars[tid].getActualFieldVariable<RealVectorValue>(name);
265  if (var)
266  {
267  if (var->feType().family == LAGRANGE_VEC)
268  _nodal_vars[tid].push_back(var);
269  else
270  _elem_vars[tid].push_back(var);
271  }
272  }
273 
274  else
275  {
276  MooseVariableBase * var_base = _vars[tid].getVariable(name);
277 
278  auto * const var = dynamic_cast<MooseVariableField<Real> *>(var_base);
279 
280  if (var)
281  {
282  if (var->feType().family == LAGRANGE)
283  _nodal_vars[tid].push_back(var);
284  else
285  _elem_vars[tid].push_back(var);
286  }
287 
288  auto * const avar = dynamic_cast<MooseVariableField<RealEigenVector> *>(var_base);
289 
290  if (avar)
291  {
292  if (avar->feType().family == LAGRANGE)
293  _nodal_vars[tid].push_back(avar);
294  else
295  _elem_vars[tid].push_back(avar);
296  }
297  }
298  }
299 }
300 
301 void
302 AuxiliarySystem::addKernel(const std::string & kernel_name,
303  const std::string & name,
304  InputParameters & parameters)
305 {
306  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
307  {
308  const auto & base = parameters.getBase();
309  if (base == "AuxKernel" || base == "Bounds")
310  {
311  std::shared_ptr<AuxKernel> kernel =
312  _factory.create<AuxKernel>(kernel_name, name, parameters, tid);
313  if (kernel->isNodal())
314  {
315  if (kernel->isMortar())
316  _mortar_nodal_aux_storage.addObject(kernel, tid);
317  else
318  _nodal_aux_storage.addObject(kernel, tid);
319  }
320  else
321  _elemental_aux_storage.addObject(kernel, tid);
322  }
323 
324  else if (base == "VectorAuxKernel")
325  {
326  std::shared_ptr<VectorAuxKernel> kernel =
327  _factory.create<VectorAuxKernel>(kernel_name, name, parameters, tid);
328  if (kernel->isNodal())
329  {
330  if (kernel->isMortar())
331  mooseError("Vector mortar aux kernels not yet implemented");
332  _nodal_vec_aux_storage.addObject(kernel, tid);
333  }
334  else
335  _elemental_vec_aux_storage.addObject(kernel, tid);
336  }
337 
338  else if (base == "ArrayAuxKernel")
339  {
340  std::shared_ptr<ArrayAuxKernel> kernel =
341  _factory.create<ArrayAuxKernel>(kernel_name, name, parameters, tid);
342  if (kernel->isNodal())
343  {
344  if (kernel->isMortar())
345  mooseError("Vector mortar aux kernels not yet implemented");
346  _nodal_array_aux_storage.addObject(kernel, tid);
347  }
348  else
349  _elemental_array_aux_storage.addObject(kernel, tid);
350  }
351  else
352  mooseAssert(false,
353  "Attempting to add AuxKernel of type '" + kernel_name + "' and name '" + name +
354  "' to the auxiliary system with invalid _moose_base: " + base);
355  }
356 }
357 
358 void
359 AuxiliarySystem::addScalarKernel(const std::string & kernel_name,
360  const std::string & name,
361  InputParameters & parameters)
362 {
363  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
364  {
365  std::shared_ptr<AuxScalarKernel> kernel =
366  _factory.create<AuxScalarKernel>(kernel_name, name, parameters, tid);
367  _aux_scalar_storage.addObject(kernel, tid);
368  }
369 }
370 
371 void
373 {
374  for (auto * var : _nodal_vars[tid])
375  var->computeElemValues();
376 
377  for (auto * var : _elem_vars[tid])
378  {
379  var->reinitAux();
380  var->computeElemValues();
381  }
382 }
383 
384 void
385 AuxiliarySystem::reinitElemFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
386 {
387  for (auto * var : _nodal_vars[tid])
388  var->computeElemValuesFace();
389 
390  for (auto * var : _elem_vars[tid])
391  {
392  var->reinitAux();
393  var->reinitAuxNeighbor();
394  var->computeElemValuesFace();
395  }
396 }
397 
398 void
400 {
401  if (_serialized_solution.get() &&
402  _sys.n_dofs() > 0) // libMesh does not like serializing of empty vectors
403  {
404  if (!_serialized_solution->initialized() || _serialized_solution->size() != _sys.n_dofs())
405  {
406  _serialized_solution->clear();
407  _serialized_solution->init(_sys.n_dofs(), false, SERIAL);
408  }
409 
411  }
412 }
413 
414 void
416 {
417  // avoid division by dt which might be zero.
418  if (_fe_problem.dt() > 0.)
419  for (auto & ti : _time_integrators)
420  ti->preStep();
421 
422  // We need to compute time derivatives every time each kind of the variables is finished, because:
423  //
424  // a) the user might want to use the aux variable value somewhere, thus we need to provide the
425  // up-to-date value
426  // b) time integration system works with the whole vectors of solutions, thus we cannot update
427  // only a part of the vector
428  //
429 
430  if (_vars[0].scalars().size() > 0)
431  {
432  computeScalarVars(type);
433  // compute time derivatives of scalar aux variables _after_ the values were updated
434  if (_fe_problem.dt() > 0.)
435  for (auto & ti : _time_integrators)
436  ti->computeTimeDerivatives();
437  }
438 
439  if (_vars[0].fieldVariables().size() > 0)
440  {
441  computeNodalArrayVars(type);
442  computeNodalVecVars(type);
443  computeNodalVars(type);
447  computeElementalVars(type);
448 
449 #ifdef MOOSE_KOKKOS_ENABLED
450  kokkosCompute(type);
451 #endif
452 
453  // compute time derivatives of nodal aux variables _after_ the values were updated
454  if (_fe_problem.dt() > 0.)
455  for (auto & ti : _time_integrators)
456  ti->computeTimeDerivatives();
457  }
458 
459  if (_serialized_solution.get())
461 }
462 
463 std::set<std::string>
465 {
466  std::set<std::string> depend_objects;
467 
468  // Elemental AuxKernels
469  {
470  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
471  _elemental_aux_storage[type].getActiveObjects();
472  for (const auto & aux : auxs)
473  {
474  const std::set<UserObjectName> & uo = aux->getDependObjects();
475  depend_objects.insert(uo.begin(), uo.end());
476  }
477  }
478 
479  // Elemental VectorAuxKernels
480  {
481  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
482  _elemental_vec_aux_storage[type].getActiveObjects();
483  for (const auto & aux : auxs)
484  {
485  const std::set<UserObjectName> & uo = aux->getDependObjects();
486  depend_objects.insert(uo.begin(), uo.end());
487  }
488  }
489 
490  // Elemental ArrayAuxKernels
491  {
492  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
493  _elemental_array_aux_storage[type].getActiveObjects();
494  for (const auto & aux : auxs)
495  {
496  const std::set<UserObjectName> & uo = aux->getDependObjects();
497  depend_objects.insert(uo.begin(), uo.end());
498  }
499  }
500 
501  // Nodal AuxKernels
502  {
503  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
504  _nodal_aux_storage[type].getActiveObjects();
505  for (const auto & aux : auxs)
506  {
507  const std::set<UserObjectName> & uo = aux->getDependObjects();
508  depend_objects.insert(uo.begin(), uo.end());
509  }
510  }
511 
512  // Mortar Nodal AuxKernels
513  {
514  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
515  _mortar_nodal_aux_storage[type].getActiveObjects();
516  for (const auto & aux : auxs)
517  {
518  const std::set<UserObjectName> & uo = aux->getDependObjects();
519  depend_objects.insert(uo.begin(), uo.end());
520  }
521  }
522 
523  // Nodal VectorAuxKernels
524  {
525  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
526  _nodal_vec_aux_storage[type].getActiveObjects();
527  for (const auto & aux : auxs)
528  {
529  const std::set<UserObjectName> & uo = aux->getDependObjects();
530  depend_objects.insert(uo.begin(), uo.end());
531  }
532  }
533 
534  // Nodal ArrayAuxKernels
535  {
536  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
537  _nodal_array_aux_storage[type].getActiveObjects();
538  for (const auto & aux : auxs)
539  {
540  const std::set<UserObjectName> & uo = aux->getDependObjects();
541  depend_objects.insert(uo.begin(), uo.end());
542  }
543  }
544 
545 #ifdef MOOSE_KOKKOS_ENABLED
546  // Nodal KokkosAuxKernels
547  {
548  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
550  for (const auto & aux : auxs)
551  {
552  const std::set<UserObjectName> & uo = aux->getDependObjects();
553  depend_objects.insert(uo.begin(), uo.end());
554  }
555  }
556 
557  // Nodal ElementalAuxKernels
558  {
559  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
561  for (const auto & aux : auxs)
562  {
563  const std::set<UserObjectName> & uo = aux->getDependObjects();
564  depend_objects.insert(uo.begin(), uo.end());
565  }
566  }
567 #endif
568 
569  return depend_objects;
570 }
571 
572 std::set<std::string>
574 {
575  std::set<std::string> depend_objects;
576 
577  // Elemental AuxKernels
578  {
579  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
580  _elemental_aux_storage.getActiveObjects();
581  for (const auto & aux : auxs)
582  {
583  const std::set<UserObjectName> & uo = aux->getDependObjects();
584  depend_objects.insert(uo.begin(), uo.end());
585  }
586  }
587 
588  // Elemental VectorAuxKernels
589  {
590  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
591  _elemental_vec_aux_storage.getActiveObjects();
592  for (const auto & aux : auxs)
593  {
594  const std::set<UserObjectName> & uo = aux->getDependObjects();
595  depend_objects.insert(uo.begin(), uo.end());
596  }
597  }
598 
599  // Elemental ArrayAuxKernels
600  {
601  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
602  _elemental_array_aux_storage.getActiveObjects();
603  for (const auto & aux : auxs)
604  {
605  const std::set<UserObjectName> & uo = aux->getDependObjects();
606  depend_objects.insert(uo.begin(), uo.end());
607  }
608  }
609 
610  // Nodal AuxKernels
611  {
612  const std::vector<std::shared_ptr<AuxKernel>> & auxs = _nodal_aux_storage.getActiveObjects();
613  for (const auto & aux : auxs)
614  {
615  const std::set<UserObjectName> & uo = aux->getDependObjects();
616  depend_objects.insert(uo.begin(), uo.end());
617  }
618  }
619 
620  // Mortar Nodal AuxKernels
621  {
622  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
623  _mortar_nodal_aux_storage.getActiveObjects();
624  for (const auto & aux : auxs)
625  {
626  const std::set<UserObjectName> & uo = aux->getDependObjects();
627  depend_objects.insert(uo.begin(), uo.end());
628  }
629  }
630 
631  // Nodal VectorAuxKernels
632  {
633  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
634  _nodal_vec_aux_storage.getActiveObjects();
635  for (const auto & aux : auxs)
636  {
637  const std::set<UserObjectName> & uo = aux->getDependObjects();
638  depend_objects.insert(uo.begin(), uo.end());
639  }
640  }
641 
642  // Nodal ArrayAuxKernels
643  {
644  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
645  _nodal_array_aux_storage.getActiveObjects();
646  for (const auto & aux : auxs)
647  {
648  const std::set<UserObjectName> & uo = aux->getDependObjects();
649  depend_objects.insert(uo.begin(), uo.end());
650  }
651  }
652 
653 #ifdef MOOSE_KOKKOS_ENABLED
654  // Nodal KokkosAuxKernels
655  {
656  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
658  for (const auto & aux : auxs)
659  {
660  const std::set<UserObjectName> & uo = aux->getDependObjects();
661  depend_objects.insert(uo.begin(), uo.end());
662  }
663  }
664 
665  // Elemental KokkosAuxKernels
666  {
667  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
669  for (const auto & aux : auxs)
670  {
671  const std::set<UserObjectName> & uo = aux->getDependObjects();
672  depend_objects.insert(uo.begin(), uo.end());
673  }
674  }
675 #endif
676 
677  return depend_objects;
678 }
679 
680 void
682 {
684  const std::vector<std::shared_ptr<AuxScalarKernel>> & objects = storage.getActiveObjects(0);
685 
686  std::set<TagID> needed_sc_var_matrix_tags;
687  std::set<TagID> needed_sc_var_vector_tags;
688  for (const auto & obj : objects)
689  {
690  auto & sc_var_coup_vtags = obj->getScalarVariableCoupleableVectorTags();
691  needed_sc_var_vector_tags.insert(sc_var_coup_vtags.begin(), sc_var_coup_vtags.end());
692 
693  auto & sc_var_coup_mtags = obj->getScalarVariableCoupleableMatrixTags();
694  needed_sc_var_matrix_tags.insert(sc_var_coup_mtags.begin(), sc_var_coup_mtags.end());
695  }
696 
697  _fe_problem.setActiveScalarVariableCoupleableMatrixTags(needed_sc_var_matrix_tags, 0);
698  _fe_problem.setActiveScalarVariableCoupleableVectorTags(needed_sc_var_vector_tags, 0);
699 }
700 
701 void
703 {
706 }
707 
708 void
710 {
712 
713  // Reference to the current storage container
715 
716  if (storage.hasActiveObjects())
717  {
718  TIME_SECTION("computeScalarVars", 1);
719 
720  PARALLEL_TRY
721  {
722  // FIXME: run multi-threaded
723  THREAD_ID tid = 0;
724  if (storage.hasActiveObjects())
725  {
727 
728  const std::vector<std::shared_ptr<AuxScalarKernel>> & objects =
729  storage.getActiveObjects(tid);
730 
731  // Call compute() method on all active AuxScalarKernel objects
732  for (const auto & obj : objects)
733  obj->compute();
734 
735  const std::vector<MooseVariableScalar *> & scalar_vars = getScalarVariables(tid);
736  for (const auto & var : scalar_vars)
737  var->insert(solution());
738  }
739  }
740  PARALLEL_CATCH;
741 
742  solution().close();
743  _sys.update();
744  }
745 
747 }
748 
749 void
751 {
752  TIME_SECTION("computeNodalVars", 3);
753 
755  computeNodalVarsHelper<AuxKernel>(nodal);
756 }
757 
758 void
760 {
761  TIME_SECTION("computeNodalVecVars", 3);
762 
764  computeNodalVarsHelper<VectorAuxKernel>(nodal);
765 }
766 
767 void
769 {
771  computeNodalVarsHelper<ArrayAuxKernel>(nodal);
772 }
773 
774 void
776 {
777  TIME_SECTION("computeMortarNodalVars", 3);
778 
779  const MooseObjectWarehouse<AuxKernel> & mortar_nodal_warehouse = _mortar_nodal_aux_storage[type];
780 
781  mooseAssert(!mortar_nodal_warehouse.hasActiveBlockObjects(),
782  "We don't allow creation of block restricted mortar nodal aux kernels.");
783 
784  if (mortar_nodal_warehouse.hasActiveBoundaryObjects())
785  {
787  for (const auto & [bnd_id, mortar_nodal_auxes] :
788  mortar_nodal_warehouse.getActiveBoundaryObjects())
789  for (const auto index : index_range(mortar_nodal_auxes))
790  {
791  PARALLEL_TRY
792  {
793  try
794  {
796  _fe_problem, mortar_nodal_warehouse, bnd_id, index);
797  Threads::parallel_reduce(bnd_nodes, mnabt);
798  }
799  catch (MooseException & e)
800  {
801  _fe_problem.setException("The following MooseException was raised during mortar nodal "
802  "Auxiliary variable computation:\n" +
803  std::string(e.what()));
804  }
805  catch (MetaPhysicL::LogicError & e)
806  {
808  }
809  catch (std::exception & e)
810  {
811  // Continue if we find a libMesh degenerate map exception, but
812  // just re-throw for any real error
813  if (!strstr(e.what(), "Jacobian") && !strstr(e.what(), "singular") &&
814  !strstr(e.what(), "det != 0"))
815  throw;
816 
817  _fe_problem.setException("We caught a libMesh degeneracy exception during mortar "
818  "nodal Auxiliary variable computation:\n" +
819  std::string(e.what()));
820  }
821  }
822  PARALLEL_CATCH;
823 
824  // We need to make sure we propagate exceptions to all processes before trying to close
825  // here, which is a parallel operation
826  solution().close();
827  _sys.update();
828  }
829  }
830 }
831 
832 void
834 {
835  TIME_SECTION("computeElementalVars", 3);
836 
838  computeElementalVarsHelper<AuxKernel>(elemental);
839 }
840 
841 void
843 {
844  TIME_SECTION("computeElementalVecVars", 3);
845 
847  computeElementalVarsHelper<VectorAuxKernel>(elemental);
848 }
849 
850 void
852 {
854  computeElementalVarsHelper<ArrayAuxKernel>(elemental);
855 }
856 
857 void
859  std::vector<dof_id_type> & /*n_nz*/,
860  std::vector<dof_id_type> &
861  /*n_oz*/)
862 {
863 }
864 
865 Order
867 {
868  Order order = CONSTANT;
869  std::vector<MooseVariableFEBase *> vars = _vars[0].fieldVariables();
870  for (const auto & var : vars)
871  {
872  if (!var->isNodal()) // nodal aux variables do not need quadrature
873  {
874  FEType fe_type = var->feType();
875  if (fe_type.default_quadrature_order() > order)
876  order = fe_type.default_quadrature_order();
877  }
878  }
879 
880  return order;
881 }
882 
883 bool
885 {
886  return _elemental_aux_storage.hasActiveBoundaryObjects(bnd_id) ||
887  _elemental_vec_aux_storage.hasActiveBoundaryObjects(bnd_id);
888 }
889 
890 void
892 {
895 }
896 
897 template <typename AuxKernelType>
898 void
900 {
901  if (warehouse.hasActiveBlockObjects())
902  {
903  // Block Elemental AuxKernels
904  PARALLEL_TRY
905  {
908  try
909  {
910  Threads::parallel_reduce(range, eavt);
911  }
912  catch (MooseException & e)
913  {
914  _fe_problem.setException("The following MooseException was raised during elemental "
915  "Auxiliary variable computation:\n" +
916  std::string(e.what()));
917  }
918  }
919  PARALLEL_CATCH;
920 
921  // We need to make sure we propagate exceptions to all processes before trying to close
922  // here, which is a parallel operation
923  solution().close();
924  _sys.update();
925  }
926 
927  // Boundary Elemental AuxKernels
928  if (warehouse.hasActiveBoundaryObjects())
929  {
930  TIME_SECTION("computeElementalVecVars", 3);
931 
932  PARALLEL_TRY
933  {
936  try
937  {
938  Threads::parallel_reduce(bnd_elems, eabt);
939  }
940  catch (MooseException & e)
941  {
942  _fe_problem.setException("The following MooseException was raised during boundary "
943  "elemental Auxiliary variable computation:\n" +
944  std::string(e.what()));
945  }
946  }
947  PARALLEL_CATCH;
948 
949  // We need to make sure we propagate exceptions to all processes before trying to close
950  // here, which is a parallel operation
951  solution().close();
952  _sys.update();
953  }
954 }
955 
956 template <typename AuxKernelType>
957 void
959 {
960  if (warehouse.hasActiveBlockObjects())
961  {
962  // Block Nodal AuxKernels
963  PARALLEL_TRY
964  {
967  Threads::parallel_reduce(range, navt);
968 
969  solution().close();
970  _sys.update();
971  }
972  PARALLEL_CATCH;
973  }
974 
975  if (warehouse.hasActiveBoundaryObjects())
976  {
977  TIME_SECTION("computeBoundaryObjects", 3);
978 
979  // Boundary Nodal AuxKernels
980  PARALLEL_TRY
981  {
984  Threads::parallel_reduce(bnd_nodes, nabt);
985 
986  solution().close();
987  _sys.update();
988  }
989  PARALLEL_CATCH;
990  }
991 }
992 
993 void
995  std::vector<Number> & rel_diff_norms) const
996 {
997  rel_diff_norms.resize(nVariables(), 0);
998  // Get dof map from system
999  const auto & dof_map = _sys.get_dof_map();
1000 
1001  for (const auto n : make_range(nVariables()))
1002  {
1003  // Get local indices from dof map for each variable
1004  std::vector<dof_id_type> local_indices_n;
1005  dof_map.local_variable_indices(local_indices_n, _mesh, n);
1006  Number diff_norm_n = 0;
1007  Number norm_n = 0;
1008  // Get values from system, update norm
1009  for (const auto local_index : local_indices_n)
1010  {
1011  const Number & value = solution()(local_index);
1012  const Number & value_old = solutionOld()(local_index);
1013  diff_norm_n += Utility::pow<2, Number>(value - value_old);
1014  norm_n += Utility::pow<2, Number>(value);
1015  }
1016  // Aggregate norm over proceccors
1017  _communicator.sum(diff_norm_n);
1018  _communicator.sum(norm_n);
1019  diff_norm_n = sqrt(diff_norm_n);
1020  norm_n = sqrt(norm_n);
1021  rel_diff_norms[n] = diff_norm_n / norm_n;
1022  }
1023 }
1024 
1025 template void
1026 AuxiliarySystem::computeElementalVarsHelper<AuxKernel>(const MooseObjectWarehouse<AuxKernel> &);
1027 template void AuxiliarySystem::computeElementalVarsHelper<VectorAuxKernel>(
1029 template void
1030 AuxiliarySystem::computeNodalVarsHelper<AuxKernel>(const MooseObjectWarehouse<AuxKernel> &);
1031 template void AuxiliarySystem::computeNodalVarsHelper<VectorAuxKernel>(
std::string name(const ElemQuality q)
std::vector< std::shared_ptr< TimeIntegrator > > _time_integrators
Time integrator.
Definition: SystemBase.h:1049
void addObject(std::shared_ptr< T > object, THREAD_ID tid=0, bool recurse=true) override
Adds an object to the storage structure.
LAGRANGE
ExecuteMooseObjectWarehouse< AuxKernel > _nodal_aux_storage
ExecuteMooseObjectWarehouse< AuxKernel > _mortar_nodal_aux_storage
virtual void timestepSetup() override
libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
Definition: MooseMesh.C:1288
Order
virtual void clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid) override
void computeNodalVarsHelper(const MooseObjectWarehouse< AuxKernelType > &warehouse)
virtual const char * what() const
Get out the error message.
unsigned int n_threads()
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition: SystemBase.h:756
bool hasActiveBlockObjects(THREAD_ID tid=0) const
void computeScalarVars(ExecFlagType type)
void sort(THREAD_ID tid=0)
Performs a sort using the DependencyResolver.
LAGRANGE_VEC
This class evaluates a single mortar nodal aux kernel.
NumericVector< Number > & solution()
Definition: SystemBase.h:196
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &parameters)
Canonical method for adding a variable.
Definition: SystemBase.C:718
virtual void copyCurrentIntoPreviousNL()
Copies the current solution into the previous nonlinear iteration solution.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
virtual void clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid) override
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void updateActive(THREAD_ID tid=0) override
Updates the active objects storage.
virtual void setActiveScalarVariableCoupleableMatrixTags(std::set< TagID > &mtags, const THREAD_ID tid) override
virtual void reinitScalars(const THREAD_ID tid, bool reinit_for_derivative_reordering=false) override
fills the VariableValue arrays for scalar variables from the solution vector
void local_variable_indices(T &idx, const MeshBase &mesh, unsigned int var_num) const
void translateMetaPhysicLError(const MetaPhysicL::LogicError &)
emit a relatively clear error message when we catch a MetaPhysicL logic error
Definition: MooseError.C:141
char ** vars
AuxiliarySystem(FEProblemBase &subproblem, const std::string &name)
ExecuteMooseObjectWarehouse< ArrayAuxKernel > _nodal_array_aux_storage
virtual void updateActive(THREAD_ID tid)
virtual void setException(const std::string &message)
Set an exception, which is stored at this point by toggling a member variable in this class...
virtual void customSetup(const ExecFlagType &exec_type, THREAD_ID tid=0) const
Factory & _factory
Definition: SystemBase.h:989
const NumericVector< Number > *const & currentSolution() const override
The solution vector that is currently being operated on.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Order default_quadrature_order() const
void computeElementalVarsHelper(const MooseObjectWarehouse< AuxKernelType > &warehouse)
const Parallel::Communicator & _communicator
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Base class for a system (of equations)
Definition: SystemBase.h:84
ExecuteMooseObjectWarehouse< AuxScalarKernel > _aux_scalar_storage
bool needMaterialOnSide(BoundaryID bnd_id)
Indicated whether this system needs material properties on boundaries.
virtual void reinitElem(const Elem *elem, THREAD_ID tid) override
Reinit an element assembly info.
std::unique_ptr< NumericVector< Number > > _serialized_solution
Serialized version of the solution vector, or nullptr if a serialized solution is not needed...
Definition: SystemBase.h:1068
virtual void residualSetup() override
libMesh::ConstNodeRange * getLocalNodeRange()
Definition: MooseMesh.C:1325
const std::string & getBase() const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
FEProblemBase & _fe_problem
Definition: Split.h:45
void computeMortarNodalVars(ExecFlagType type)
dof_id_type n_dofs() const
virtual unsigned int nVariables() const
Get the number of variables in this system.
Definition: SystemBase.C:891
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
virtual const std::string & name() const
Definition: SystemBase.C:1340
virtual void jacobianSetup()
Definition: SystemBase.C:1606
ExecuteMooseObjectWarehouse< AuxKernelBase > _kokkos_elemental_aux_storage
void setScalarVariableCoupleableTags(ExecFlagType type)
void clearScalarVariableCoupleableTags()
std::set< std::string > getDependObjects()
virtual void jacobianSetup() override
ExecuteMooseObjectWarehouse< ArrayAuxKernel > _elemental_array_aux_storage
CONSTANT
SERIAL
const std::vector< std::shared_ptr< T > > & getActiveObjects(THREAD_ID tid=0) const
Retrieve complete vector to the active all/block/boundary restricted objects for a given thread...
void computeNodalArrayVars(ExecFlagType type)
virtual std::unique_ptr< Base > create()=0
void computeElementalVars(ExecFlagType type)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
Base class for making kernels that work on auxiliary scalar variables.
boundary_id_type BoundaryID
virtual void timestepSetup(THREAD_ID tid=0) const
virtual libMesh::Order getMinQuadratureOrder() override
Get the minimum quadrature order for evaluating elemental auxiliary variables.
virtual void setActiveScalarVariableCoupleableVectorTags(std::set< TagID > &vtags, const THREAD_ID tid) override
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
void kokkosCompute(ExecFlagType type)
virtual void initialSetup(THREAD_ID tid=0) const
Convenience methods for calling object setup methods.
virtual void addVariable(const std::string &var_type, const std::string &name, InputParameters &parameters) override
Canonical method for adding a variable.
Interface for objects interacting with the PerfGraph.
virtual void close()=0
void jacobianSetup(THREAD_ID tid=0) const override
Convenience methods for calling object setup methods.
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
virtual void reinitElemFace(const Elem *elem, unsigned int side, THREAD_ID tid) override
Reinit assembly info for a side of an element.
virtual ~AuxiliarySystem()
virtual void augmentSparsity(libMesh::SparsityPattern::Graph &, std::vector< dof_id_type > &, std::vector< dof_id_type > &) override
Will modify the sparsity pattern to add logical geometric connections.
std::vector< std::vector< MooseVariableFEBase * > > _nodal_vars
virtual void initialSetup() override
Setup Functions.
ExecuteMooseObjectWarehouse< VectorAuxKernel > _nodal_vec_aux_storage
std::vector< std::vector< MooseVariableFieldBase * > > _elem_vars
Elemental variables.
ExecuteMooseObjectWarehouse< AuxKernelBase > _kokkos_nodal_aux_storage
FEProblemBase & _fe_problem
the governing finite element/volume problem
Definition: SystemBase.h:986
std::vector< VariableWarehouse > _vars
Variable warehouses (one for each thread)
Definition: SystemBase.h:996
Provides a way for users to bail out of the current solve.
virtual void update()
virtual void subdomainSetup()
Definition: SystemBase.C:1592
void addKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
Adds an auxiliary kernel.
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
MooseMesh & _mesh
Definition: SystemBase.h:991
bool hasActiveObjects(THREAD_ID tid=0) const
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
virtual void compute(ExecFlagType type) override
Compute auxiliary variables.
IntRange< T > make_range(T beg, T end)
void computeNodalVars(ExecFlagType type)
virtual const NumericVector< Number > * solutionPreviousNewton() const
Definition: SystemBase.C:1355
virtual void customSetup(const ExecFlagType &exec_type)
Definition: SystemBase.C:1585
void addScalarKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
Adds a scalar kernel.
ExecuteMooseObjectWarehouse< AuxKernel > _elemental_aux_storage
virtual void customSetup(const ExecFlagType &exec_type) override
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
Definition: MooseMesh.C:1353
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
virtual void serializeSolution()
void computeNodalVecVars(ExecFlagType type)
Real Number
void computeElementalArrayVars(ExecFlagType type)
ExecuteMooseObjectWarehouse< VectorAuxKernel > _elemental_vec_aux_storage
NumericVector< Number > & solutionOld()
Definition: SystemBase.h:197
virtual void initialSetup()
Setup Functions.
Definition: SystemBase.C:1558
bool defaultGhosting()
Whether or not the user has requested default ghosting ot be on.
Definition: SubProblem.h:144
TYPE_VECTOR
virtual Real & dt() const
libMesh::System & _sys
const DofMap & get_dof_map() const
virtual void residualSetup()
Definition: SystemBase.C:1599
void residualSetup(THREAD_ID tid=0) const override
virtual void subdomainSetup(THREAD_ID tid=0) const
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
Definition: MooseMesh.C:1339
auto index_range(const T &sizable)
void variableWiseRelativeSolutionDifferenceNorm(std::vector< Number > &var_diffs) const
Computes and stores ||current - old|| / ||current|| for each variable in the given vector...
const Elem & get(const ElemType type_in)
void computeElementalVecVars(ExecFlagType type)
Base variable class.
unsigned int THREAD_ID
Definition: MooseTypes.h:237
virtual void subdomainSetup() override
virtual void timestepSetup()
Definition: SystemBase.C:1578
virtual void localize(std::vector< T > &v_local) const=0