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  LinearFVGradientInterface(static_cast<SystemBase &>(*this)),
45  _sys(subproblem.es().add_system<System>(name)),
46  _current_solution(_sys.current_local_solution.get()),
47  _aux_scalar_storage(_app.getExecuteOnEnum()),
48  _nodal_aux_storage(_app.getExecuteOnEnum()),
49  _mortar_nodal_aux_storage(_app.getExecuteOnEnum()),
50  _elemental_aux_storage(_app.getExecuteOnEnum()),
51  _nodal_vec_aux_storage(_app.getExecuteOnEnum()),
52  _elemental_vec_aux_storage(_app.getExecuteOnEnum()),
53  _nodal_array_aux_storage(_app.getExecuteOnEnum()),
54  _elemental_array_aux_storage(_app.getExecuteOnEnum())
55 #ifdef MOOSE_KOKKOS_ENABLED
56  ,
57  _kokkos_nodal_aux_storage(_app.getExecuteOnEnum()),
58  _kokkos_elemental_aux_storage(_app.getExecuteOnEnum())
59 #endif
60 {
61  _nodal_vars.resize(libMesh::n_threads());
62  _elem_vars.resize(libMesh::n_threads());
63 
65  {
66  auto & dof_map = _sys.get_dof_map();
67  dof_map.remove_algebraic_ghosting_functor(dof_map.default_algebraic_ghosting());
68  dof_map.set_implicit_neighbor_dofs(false);
69  }
70 }
71 
73 
74 void
76 {
77  TIME_SECTION("initialSetup", 3, "Initializing Auxiliary System");
78 
82 
83  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
84  {
87 
88  _nodal_aux_storage.sort(tid);
89  _nodal_aux_storage.initialSetup(tid);
90 
91  _mortar_nodal_aux_storage.sort(tid);
92  _mortar_nodal_aux_storage.initialSetup(tid);
93 
94  _nodal_vec_aux_storage.sort(tid);
95  _nodal_vec_aux_storage.initialSetup(tid);
96 
97  _nodal_array_aux_storage.sort(tid);
98  _nodal_array_aux_storage.initialSetup(tid);
99 
100  _elemental_aux_storage.sort(tid);
101  _elemental_aux_storage.initialSetup(tid);
102 
103  _elemental_vec_aux_storage.sort(tid);
104  _elemental_vec_aux_storage.initialSetup(tid);
105 
107  _elemental_array_aux_storage.initialSetup(tid);
108  }
109 
110 #ifdef MOOSE_KOKKOS_ENABLED
111  _kokkos_nodal_aux_storage.sort(/*tid=*/0);
113 
116 #endif
117 }
118 
119 void
121 {
124 }
125 
126 void
128 {
130 
131  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
132  {
134  _nodal_aux_storage.timestepSetup(tid);
135  _mortar_nodal_aux_storage.timestepSetup(tid);
136  _nodal_vec_aux_storage.timestepSetup(tid);
137  _nodal_array_aux_storage.timestepSetup(tid);
138  _elemental_aux_storage.timestepSetup(tid);
139  _elemental_vec_aux_storage.timestepSetup(tid);
140  _elemental_array_aux_storage.timestepSetup(tid);
141  }
142 
143 #ifdef MOOSE_KOKKOS_ENABLED
146 #endif
147 }
148 
149 void
151 {
152  SystemBase::customSetup(exec_type);
153 
154  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
155  {
156  _aux_scalar_storage.customSetup(exec_type, tid);
157  _nodal_aux_storage.customSetup(exec_type, tid);
158  _mortar_nodal_aux_storage.customSetup(exec_type, tid);
159  _nodal_vec_aux_storage.customSetup(exec_type, tid);
160  _nodal_array_aux_storage.customSetup(exec_type, tid);
161  _elemental_aux_storage.customSetup(exec_type, tid);
162  _elemental_vec_aux_storage.customSetup(exec_type, tid);
163  _elemental_array_aux_storage.customSetup(exec_type, tid);
164  }
165 
166 #ifdef MOOSE_KOKKOS_ENABLED
167  _kokkos_nodal_aux_storage.customSetup(exec_type, /*tid=*/0);
168  _kokkos_elemental_aux_storage.customSetup(exec_type, /*tid=*/0);
169 #endif
170 }
171 
172 void
174 {
176 
177  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
178  {
180  _nodal_aux_storage.subdomainSetup(tid);
181  _mortar_nodal_aux_storage.subdomainSetup(tid);
182  _nodal_vec_aux_storage.subdomainSetup(tid);
183  _nodal_array_aux_storage.subdomainSetup(tid);
184  _elemental_aux_storage.subdomainSetup(tid);
185  _elemental_vec_aux_storage.subdomainSetup(tid);
186  _elemental_array_aux_storage.subdomainSetup(tid);
187  }
188 }
189 
190 void
192 {
194 
195  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
196  {
198  _nodal_aux_storage.jacobianSetup(tid);
199  _mortar_nodal_aux_storage.jacobianSetup(tid);
200  _nodal_vec_aux_storage.jacobianSetup(tid);
201  _nodal_array_aux_storage.jacobianSetup(tid);
202  _elemental_aux_storage.jacobianSetup(tid);
203  _elemental_vec_aux_storage.jacobianSetup(tid);
204  _elemental_array_aux_storage.jacobianSetup(tid);
205  }
206 
207 #ifdef MOOSE_KOKKOS_ENABLED
210 #endif
211 }
212 
213 void
215 {
217 
218  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
219  {
221  _nodal_aux_storage.residualSetup(tid);
222  _mortar_nodal_aux_storage.residualSetup(tid);
223  _nodal_vec_aux_storage.residualSetup(tid);
224  _nodal_array_aux_storage.residualSetup(tid);
225  _elemental_aux_storage.residualSetup(tid);
226  _elemental_vec_aux_storage.residualSetup(tid);
227  _elemental_array_aux_storage.residualSetup(tid);
228  }
229 
230 #ifdef MOOSE_KOKKOS_ENABLED
233 #endif
234 }
235 
236 void
238 {
240  _nodal_aux_storage.updateActive(tid);
241  _mortar_nodal_aux_storage.updateActive(tid);
242  _nodal_vec_aux_storage.updateActive(tid);
243  _nodal_array_aux_storage.updateActive(tid);
244  _elemental_aux_storage.updateActive(tid);
245  _elemental_vec_aux_storage.updateActive(tid);
246  _elemental_array_aux_storage.updateActive(tid);
247 
248 #ifdef MOOSE_KOKKOS_ENABLED
249  if (tid == 0)
250  {
253  }
254 #endif
255 }
256 
257 void
258 AuxiliarySystem::addVariable(const std::string & var_type,
259  const std::string & name,
260  InputParameters & parameters)
261 {
262  SystemBase::addVariable(var_type, name, parameters);
263 
264  auto fe_type = FEType(Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")),
265  Utility::string_to_enum<FEFamily>(parameters.get<MooseEnum>("family")));
266 
267  if (var_type == "MooseVariableScalar")
268  return;
269 
270  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
271  {
272  if (FEInterface::field_type(fe_type) == TYPE_VECTOR)
273  {
274  auto * var = _vars[tid].getActualFieldVariable<RealVectorValue>(name);
275  if (var)
276  {
277  if (var->feType().family == LAGRANGE_VEC)
278  _nodal_vars[tid].push_back(var);
279  else
280  _elem_vars[tid].push_back(var);
281  }
282  }
283 
284  else
285  {
286  MooseVariableBase * var_base = _vars[tid].getVariable(name);
287 
288  auto * const var = dynamic_cast<MooseVariableField<Real> *>(var_base);
289 
290  if (var)
291  {
292  if (var->feType().family == LAGRANGE)
293  _nodal_vars[tid].push_back(var);
294  else
295  _elem_vars[tid].push_back(var);
296  }
297 
298  auto * const avar = dynamic_cast<MooseVariableField<RealEigenVector> *>(var_base);
299 
300  if (avar)
301  {
302  if (avar->feType().family == LAGRANGE)
303  _nodal_vars[tid].push_back(avar);
304  else
305  _elem_vars[tid].push_back(avar);
306  }
307  }
308  }
309 }
310 
311 void
312 AuxiliarySystem::addKernel(const std::string & kernel_name,
313  const std::string & name,
314  InputParameters & parameters)
315 {
316  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
317  {
318  const auto & base = parameters.getBase();
319  if (base == "AuxKernel" || base == "Bounds")
320  {
321  std::shared_ptr<AuxKernel> kernel =
322  _factory.create<AuxKernel>(kernel_name, name, parameters, tid);
323  if (kernel->isNodal())
324  {
325  if (kernel->isMortar())
326  _mortar_nodal_aux_storage.addObject(kernel, tid);
327  else
328  _nodal_aux_storage.addObject(kernel, tid);
329  }
330  else
331  _elemental_aux_storage.addObject(kernel, tid);
332  }
333 
334  else if (base == "VectorAuxKernel")
335  {
336  std::shared_ptr<VectorAuxKernel> kernel =
337  _factory.create<VectorAuxKernel>(kernel_name, name, parameters, tid);
338  if (kernel->isNodal())
339  {
340  if (kernel->isMortar())
341  mooseError("Vector mortar aux kernels not yet implemented");
342  _nodal_vec_aux_storage.addObject(kernel, tid);
343  }
344  else
345  _elemental_vec_aux_storage.addObject(kernel, tid);
346  }
347 
348  else if (base == "ArrayAuxKernel")
349  {
350  std::shared_ptr<ArrayAuxKernel> kernel =
351  _factory.create<ArrayAuxKernel>(kernel_name, name, parameters, tid);
352  if (kernel->isNodal())
353  {
354  if (kernel->isMortar())
355  mooseError("Vector mortar aux kernels not yet implemented");
356  _nodal_array_aux_storage.addObject(kernel, tid);
357  }
358  else
359  _elemental_array_aux_storage.addObject(kernel, tid);
360  }
361  else
362  mooseAssert(false,
363  "Attempting to add AuxKernel of type '" + kernel_name + "' and name '" + name +
364  "' to the auxiliary system with invalid _moose_base: " + base);
365  }
366 }
367 
368 void
369 AuxiliarySystem::addScalarKernel(const std::string & kernel_name,
370  const std::string & name,
371  InputParameters & parameters)
372 {
373  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
374  {
375  std::shared_ptr<AuxScalarKernel> kernel =
376  _factory.create<AuxScalarKernel>(kernel_name, name, parameters, tid);
377  _aux_scalar_storage.addObject(kernel, tid);
378  }
379 }
380 
381 void
383 {
384  for (auto * var : _nodal_vars[tid])
385  var->computeElemValues();
386 
387  for (auto * var : _elem_vars[tid])
388  {
389  var->reinitAux();
390  var->computeElemValues();
391  }
392 }
393 
394 void
395 AuxiliarySystem::reinitElemFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
396 {
397  for (auto * var : _nodal_vars[tid])
398  var->computeElemValuesFace();
399 
400  for (auto * var : _elem_vars[tid])
401  {
402  var->reinitAux();
403  var->reinitAuxNeighbor();
404  var->computeElemValuesFace();
405  }
406 }
407 
408 void
410 {
411  if (_serialized_solution.get() &&
412  _sys.n_dofs() > 0) // libMesh does not like serializing of empty vectors
413  {
414  if (!_serialized_solution->initialized() || _serialized_solution->size() != _sys.n_dofs())
415  {
416  _serialized_solution->clear();
417  _serialized_solution->init(_sys.n_dofs(), false, SERIAL);
418  }
419 
421  }
422 }
423 
424 void
426 {
427  // avoid division by dt which might be zero.
428  if (_fe_problem.dt() > 0.)
429  for (auto & ti : _time_integrators)
430  ti->preStep();
431 
432  // We need to compute time derivatives every time each kind of the variables is finished, because:
433  //
434  // a) the user might want to use the aux variable value somewhere, thus we need to provide the
435  // up-to-date value
436  // b) time integration system works with the whole vectors of solutions, thus we cannot update
437  // only a part of the vector
438  //
439 
440  if (_vars[0].scalars().size() > 0)
441  {
442  computeScalarVars(type);
443  // compute time derivatives of scalar aux variables _after_ the values were updated
444  if (_fe_problem.dt() > 0.)
445  for (auto & ti : _time_integrators)
446  ti->computeTimeDerivatives();
447  }
448 
449  if (_vars[0].fieldVariables().size() > 0)
450  {
451  computeNodalArrayVars(type);
452  computeNodalVecVars(type);
453  computeNodalVars(type);
457  computeElementalVars(type);
458 
459 #ifdef MOOSE_KOKKOS_ENABLED
460  kokkosCompute(type);
461 #endif
462 
463  if (!_raw_grad_container.empty())
464  {
465  solution().close();
466  _sys.update();
468  }
469 
470  // compute time derivatives of nodal aux variables _after_ the values were updated
471  if (_fe_problem.dt() > 0.)
472  for (auto & ti : _time_integrators)
473  ti->computeTimeDerivatives();
474  }
475 
476  if (_serialized_solution.get())
478 }
479 
480 std::set<std::string>
482 {
483  std::set<std::string> depend_objects;
484 
485  // Elemental AuxKernels
486  {
487  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
488  _elemental_aux_storage[type].getActiveObjects();
489  for (const auto & aux : auxs)
490  {
491  const std::set<UserObjectName> & uo = aux->getDependObjects();
492  depend_objects.insert(uo.begin(), uo.end());
493  }
494  }
495 
496  // Elemental VectorAuxKernels
497  {
498  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
499  _elemental_vec_aux_storage[type].getActiveObjects();
500  for (const auto & aux : auxs)
501  {
502  const std::set<UserObjectName> & uo = aux->getDependObjects();
503  depend_objects.insert(uo.begin(), uo.end());
504  }
505  }
506 
507  // Elemental ArrayAuxKernels
508  {
509  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
510  _elemental_array_aux_storage[type].getActiveObjects();
511  for (const auto & aux : auxs)
512  {
513  const std::set<UserObjectName> & uo = aux->getDependObjects();
514  depend_objects.insert(uo.begin(), uo.end());
515  }
516  }
517 
518  // Nodal AuxKernels
519  {
520  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
521  _nodal_aux_storage[type].getActiveObjects();
522  for (const auto & aux : auxs)
523  {
524  const std::set<UserObjectName> & uo = aux->getDependObjects();
525  depend_objects.insert(uo.begin(), uo.end());
526  }
527  }
528 
529  // Mortar Nodal AuxKernels
530  {
531  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
532  _mortar_nodal_aux_storage[type].getActiveObjects();
533  for (const auto & aux : auxs)
534  {
535  const std::set<UserObjectName> & uo = aux->getDependObjects();
536  depend_objects.insert(uo.begin(), uo.end());
537  }
538  }
539 
540  // Nodal VectorAuxKernels
541  {
542  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
543  _nodal_vec_aux_storage[type].getActiveObjects();
544  for (const auto & aux : auxs)
545  {
546  const std::set<UserObjectName> & uo = aux->getDependObjects();
547  depend_objects.insert(uo.begin(), uo.end());
548  }
549  }
550 
551  // Nodal ArrayAuxKernels
552  {
553  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
554  _nodal_array_aux_storage[type].getActiveObjects();
555  for (const auto & aux : auxs)
556  {
557  const std::set<UserObjectName> & uo = aux->getDependObjects();
558  depend_objects.insert(uo.begin(), uo.end());
559  }
560  }
561 
562 #ifdef MOOSE_KOKKOS_ENABLED
563  // Kokkos NodalAuxKernels
564  {
565  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
567  for (const auto & aux : auxs)
568  {
569  const std::set<UserObjectName> & uo = aux->getDependObjects();
570  depend_objects.insert(uo.begin(), uo.end());
571  }
572  }
573 
574  // Kokkos ElementalAuxKernels
575  {
576  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
578  for (const auto & aux : auxs)
579  {
580  const std::set<UserObjectName> & uo = aux->getDependObjects();
581  depend_objects.insert(uo.begin(), uo.end());
582  }
583  }
584 #endif
585 
586  return depend_objects;
587 }
588 
589 std::set<std::string>
591 {
592  std::set<std::string> depend_objects;
593 
594  // Elemental AuxKernels
595  {
596  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
597  _elemental_aux_storage.getActiveObjects();
598  for (const auto & aux : auxs)
599  {
600  const std::set<UserObjectName> & uo = aux->getDependObjects();
601  depend_objects.insert(uo.begin(), uo.end());
602  }
603  }
604 
605  // Elemental VectorAuxKernels
606  {
607  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
608  _elemental_vec_aux_storage.getActiveObjects();
609  for (const auto & aux : auxs)
610  {
611  const std::set<UserObjectName> & uo = aux->getDependObjects();
612  depend_objects.insert(uo.begin(), uo.end());
613  }
614  }
615 
616  // Elemental ArrayAuxKernels
617  {
618  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
619  _elemental_array_aux_storage.getActiveObjects();
620  for (const auto & aux : auxs)
621  {
622  const std::set<UserObjectName> & uo = aux->getDependObjects();
623  depend_objects.insert(uo.begin(), uo.end());
624  }
625  }
626 
627  // Nodal AuxKernels
628  {
629  const std::vector<std::shared_ptr<AuxKernel>> & auxs = _nodal_aux_storage.getActiveObjects();
630  for (const auto & aux : auxs)
631  {
632  const std::set<UserObjectName> & uo = aux->getDependObjects();
633  depend_objects.insert(uo.begin(), uo.end());
634  }
635  }
636 
637  // Mortar Nodal AuxKernels
638  {
639  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
640  _mortar_nodal_aux_storage.getActiveObjects();
641  for (const auto & aux : auxs)
642  {
643  const std::set<UserObjectName> & uo = aux->getDependObjects();
644  depend_objects.insert(uo.begin(), uo.end());
645  }
646  }
647 
648  // Nodal VectorAuxKernels
649  {
650  const std::vector<std::shared_ptr<VectorAuxKernel>> & auxs =
651  _nodal_vec_aux_storage.getActiveObjects();
652  for (const auto & aux : auxs)
653  {
654  const std::set<UserObjectName> & uo = aux->getDependObjects();
655  depend_objects.insert(uo.begin(), uo.end());
656  }
657  }
658 
659  // Nodal ArrayAuxKernels
660  {
661  const std::vector<std::shared_ptr<ArrayAuxKernel>> & auxs =
662  _nodal_array_aux_storage.getActiveObjects();
663  for (const auto & aux : auxs)
664  {
665  const std::set<UserObjectName> & uo = aux->getDependObjects();
666  depend_objects.insert(uo.begin(), uo.end());
667  }
668  }
669 
670 #ifdef MOOSE_KOKKOS_ENABLED
671  // Nodal KokkosAuxKernels
672  {
673  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
675  for (const auto & aux : auxs)
676  {
677  const std::set<UserObjectName> & uo = aux->getDependObjects();
678  depend_objects.insert(uo.begin(), uo.end());
679  }
680  }
681 
682  // Elemental KokkosAuxKernels
683  {
684  const std::vector<std::shared_ptr<AuxKernelBase>> & auxs =
686  for (const auto & aux : auxs)
687  {
688  const std::set<UserObjectName> & uo = aux->getDependObjects();
689  depend_objects.insert(uo.begin(), uo.end());
690  }
691  }
692 #endif
693 
694  return depend_objects;
695 }
696 
697 void
699 {
701  const std::vector<std::shared_ptr<AuxScalarKernel>> & objects = storage.getActiveObjects(0);
702 
703  std::set<TagID> needed_sc_var_matrix_tags;
704  std::set<TagID> needed_sc_var_vector_tags;
705  for (const auto & obj : objects)
706  {
707  auto & sc_var_coup_vtags = obj->getScalarVariableCoupleableVectorTags();
708  needed_sc_var_vector_tags.insert(sc_var_coup_vtags.begin(), sc_var_coup_vtags.end());
709 
710  auto & sc_var_coup_mtags = obj->getScalarVariableCoupleableMatrixTags();
711  needed_sc_var_matrix_tags.insert(sc_var_coup_mtags.begin(), sc_var_coup_mtags.end());
712  }
713 
714  _fe_problem.setActiveScalarVariableCoupleableMatrixTags(needed_sc_var_matrix_tags, 0);
715  _fe_problem.setActiveScalarVariableCoupleableVectorTags(needed_sc_var_vector_tags, 0);
716 }
717 
718 void
720 {
723 }
724 
725 void
727 {
729 
730  // Reference to the current storage container
732 
733  if (storage.hasActiveObjects())
734  {
735  TIME_SECTION("computeScalarVars", 1);
736 
737  PARALLEL_TRY
738  {
739  // FIXME: run multi-threaded
740  THREAD_ID tid = 0;
741  if (storage.hasActiveObjects())
742  {
744 
745  const std::vector<std::shared_ptr<AuxScalarKernel>> & objects =
746  storage.getActiveObjects(tid);
747 
748  // Call compute() method on all active AuxScalarKernel objects
749  for (const auto & obj : objects)
750  obj->compute();
751 
752  const std::vector<MooseVariableScalar *> & scalar_vars = getScalarVariables(tid);
753  for (const auto & var : scalar_vars)
754  var->insert(solution());
755  }
756  }
757  PARALLEL_CATCH;
758 
759  solution().close();
760  _sys.update();
761  }
762 
764 }
765 
766 void
768 {
769  TIME_SECTION("computeNodalVars", 3);
770 
772  computeNodalVarsHelper<AuxKernel>(nodal);
773 }
774 
775 void
777 {
778  TIME_SECTION("computeNodalVecVars", 3);
779 
781  computeNodalVarsHelper<VectorAuxKernel>(nodal);
782 }
783 
784 void
786 {
788  computeNodalVarsHelper<ArrayAuxKernel>(nodal);
789 }
790 
791 void
793 {
794  TIME_SECTION("computeMortarNodalVars", 3);
795 
796  const MooseObjectWarehouse<AuxKernel> & mortar_nodal_warehouse = _mortar_nodal_aux_storage[type];
797 
798  mooseAssert(!mortar_nodal_warehouse.hasActiveBlockObjects(),
799  "We don't allow creation of block restricted mortar nodal aux kernels.");
800 
801  if (mortar_nodal_warehouse.hasActiveBoundaryObjects())
802  {
804  for (const auto & [bnd_id, mortar_nodal_auxes] :
805  mortar_nodal_warehouse.getActiveBoundaryObjects())
806  for (const auto index : index_range(mortar_nodal_auxes))
807  {
808  PARALLEL_TRY
809  {
810  try
811  {
813  _fe_problem, mortar_nodal_warehouse, bnd_id, index);
814  Threads::parallel_reduce(bnd_nodes, mnabt);
815  }
816  catch (MooseException & e)
817  {
818  _fe_problem.setException("The following MooseException was raised during mortar nodal "
819  "Auxiliary variable computation:\n" +
820  std::string(e.what()));
821  }
822  catch (MetaPhysicL::LogicError & e)
823  {
825  }
826  catch (std::exception & e)
827  {
828  // Continue if we find a libMesh degenerate map exception, but
829  // just re-throw for any real error
830  if (!strstr(e.what(), "Jacobian") && !strstr(e.what(), "singular") &&
831  !strstr(e.what(), "det != 0"))
832  throw;
833 
834  _fe_problem.setException("We caught a libMesh degeneracy exception during mortar "
835  "nodal Auxiliary variable computation:\n" +
836  std::string(e.what()));
837  }
838  }
839  PARALLEL_CATCH;
840 
841  // We need to make sure we propagate exceptions to all processes before trying to close
842  // here, which is a parallel operation
843  solution().close();
844  _sys.update();
845  }
846  }
847 }
848 
849 void
851 {
852  TIME_SECTION("computeElementalVars", 3);
853 
855  computeElementalVarsHelper<AuxKernel>(elemental);
856 }
857 
858 void
860 {
861  TIME_SECTION("computeElementalVecVars", 3);
862 
864  computeElementalVarsHelper<VectorAuxKernel>(elemental);
865 }
866 
867 void
869 {
871  computeElementalVarsHelper<ArrayAuxKernel>(elemental);
872 }
873 
874 void
876  std::vector<dof_id_type> & /*n_nz*/,
877  std::vector<dof_id_type> &
878  /*n_oz*/)
879 {
880 }
881 
882 Order
884 {
885  Order order = CONSTANT;
886  std::vector<MooseVariableFEBase *> vars = _vars[0].fieldVariables();
887  for (const auto & var : vars)
888  {
889  if (!var->isNodal()) // nodal aux variables do not need quadrature
890  {
891  FEType fe_type = var->feType();
892  if (fe_type.default_quadrature_order() > order)
893  order = fe_type.default_quadrature_order();
894  }
895  }
896 
897  return order;
898 }
899 
900 bool
902 {
903  return _elemental_aux_storage.hasActiveBoundaryObjects(bnd_id) ||
904  _elemental_vec_aux_storage.hasActiveBoundaryObjects(bnd_id);
905 }
906 
907 void
909 {
912 }
913 
914 template <typename AuxKernelType>
915 void
917 {
918  if (warehouse.hasActiveBlockObjects())
919  {
920  // Block Elemental AuxKernels
921  PARALLEL_TRY
922  {
925  try
926  {
927  Threads::parallel_reduce(range, eavt);
928  }
929  catch (MooseException & e)
930  {
931  _fe_problem.setException("The following MooseException was raised during elemental "
932  "Auxiliary variable computation:\n" +
933  std::string(e.what()));
934  }
935  }
936  PARALLEL_CATCH;
937 
938  // We need to make sure we propagate exceptions to all processes before trying to close
939  // here, which is a parallel operation
940  solution().close();
941  _sys.update();
942  }
943 
944  // Boundary Elemental AuxKernels
945  if (warehouse.hasActiveBoundaryObjects())
946  {
947  TIME_SECTION("computeElementalVecVars", 3);
948 
949  PARALLEL_TRY
950  {
953  try
954  {
955  Threads::parallel_reduce(bnd_elems, eabt);
956  }
957  catch (MooseException & e)
958  {
959  _fe_problem.setException("The following MooseException was raised during boundary "
960  "elemental Auxiliary variable computation:\n" +
961  std::string(e.what()));
962  }
963  }
964  PARALLEL_CATCH;
965 
966  // We need to make sure we propagate exceptions to all processes before trying to close
967  // here, which is a parallel operation
968  solution().close();
969  _sys.update();
970  }
971 }
972 
973 template <typename AuxKernelType>
974 void
976 {
977  if (warehouse.hasActiveBlockObjects())
978  {
979  // Block Nodal AuxKernels
980  PARALLEL_TRY
981  {
984  Threads::parallel_reduce(range, navt);
985 
986  solution().close();
987  _sys.update();
988  }
989  PARALLEL_CATCH;
990  }
991 
992  if (warehouse.hasActiveBoundaryObjects())
993  {
994  TIME_SECTION("computeBoundaryObjects", 3);
995 
996  // Boundary Nodal AuxKernels
997  PARALLEL_TRY
998  {
1001  Threads::parallel_reduce(bnd_nodes, nabt);
1002 
1003  solution().close();
1004  _sys.update();
1005  }
1006  PARALLEL_CATCH;
1007  }
1008 }
1009 
1010 void
1012  std::vector<Number> & rel_diff_norms) const
1013 {
1014  rel_diff_norms.resize(nVariables(), 0);
1015  // Get dof map from system
1016  const auto & dof_map = _sys.get_dof_map();
1017 
1018  for (const auto n : make_range(nVariables()))
1019  {
1020  // Get local indices from dof map for each variable
1021  std::vector<dof_id_type> local_indices_n;
1022  dof_map.local_variable_indices(local_indices_n, _mesh, n);
1023  Number diff_norm_n = 0;
1024  Number norm_n = 0;
1025  // Get values from system, update norm
1026  for (const auto local_index : local_indices_n)
1027  {
1028  const Number & value = solution()(local_index);
1029  const Number & value_old = solutionOld()(local_index);
1030  diff_norm_n += Utility::pow<2, Number>(value - value_old);
1031  norm_n += Utility::pow<2, Number>(value);
1032  }
1033  // Aggregate norm over proceccors
1034  _communicator.sum(diff_norm_n);
1035  _communicator.sum(norm_n);
1036  diff_norm_n = sqrt(diff_norm_n);
1037  norm_n = sqrt(norm_n);
1038  rel_diff_norms[n] = diff_norm_n > 0 ? diff_norm_n / norm_n : 0.0;
1039  }
1040 }
1041 
1042 template void
1043 AuxiliarySystem::computeElementalVarsHelper<AuxKernel>(const MooseObjectWarehouse<AuxKernel> &);
1044 template void AuxiliarySystem::computeElementalVarsHelper<VectorAuxKernel>(
1046 template void
1047 AuxiliarySystem::computeNodalVarsHelper<AuxKernel>(const MooseObjectWarehouse<AuxKernel> &);
1048 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
void rebuildLinearFVGradientStorage()
Rebuild persistent raw and temporary gradient storage after mesh/DOF changes.
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:1261
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:759
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:197
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &parameters)
Canonical method for adding a variable.
Definition: SystemBase.C:719
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:311
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:155
char ** vars
virtual void reinit() override
Reinitialize the system when the degrees of freedom in this system have changed.
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...
const NumericVector< Number > * _current_solution
solution vector from nonlinear solver
Base class for a system (of equations)
Definition: SystemBase.h:85
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::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > _raw_grad_container
Persisted raw cell-centered gradient components keyed by spatial direction.
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:1298
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:892
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
virtual const std::string & name() const
Definition: SystemBase.C:1342
virtual void jacobianSetup()
Definition: SystemBase.C:1595
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:54
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:1581
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)
std::unique_ptr< NumericVector< Number > > current_local_solution
virtual const NumericVector< Number > * solutionPreviousNewton() const
Definition: SystemBase.C:1357
virtual void customSetup(const ExecFlagType &exec_type)
Definition: SystemBase.C:1574
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:1325
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:198
virtual void initialSetup()
Setup Functions.
Definition: SystemBase.C:1560
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:1588
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:1312
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
void computeGradients()
Compute and store raw and requested limited Green-Gauss gradients for linear FV variables.
Shared storage and allocation logic for linear finite-volume cell gradients for variables in the syst...
virtual void timestepSetup()
Definition: SystemBase.C:1567
virtual void localize(std::vector< T > &v_local) const=0