https://mooseframework.inl.gov
DisplacedProblem.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 // MOOSE includes
11 
12 #include "AuxiliarySystem.h"
13 #include "FEProblem.h"
14 #include "MooseApp.h"
15 #include "MooseMesh.h"
16 #include "NonlinearSystem.h"
17 #include "Problem.h"
19 #include "SubProblem.h"
20 #include "AllNodesSendListThread.h"
21 #include "Assembly.h"
22 #include "DisplacedProblem.h"
23 #include "libmesh/numeric_vector.h"
24 #include "libmesh/fe_interface.h"
25 #include "libmesh/mesh_base.h"
26 #include "libmesh/transient_system.h"
27 #include "libmesh/explicit_system.h"
28 
29 using namespace libMesh;
30 
32 
35 {
37  params.addClassDescription(
38  "A Problem object for providing access to the displaced finite element "
39  "mesh and associated variables.");
40  params.addPrivateParam<MooseMesh *>("mesh");
41  params.addPrivateParam<std::vector<std::string>>("displacements", {});
42  return params;
43 }
44 
46  : SubProblem(parameters),
47  _mproblem(parameters.have_parameter<FEProblemBase *>("_fe_problem_base")
48  ? *getParam<FEProblemBase *>("_fe_problem_base")
49  : *getParam<FEProblem *>("_fe_problem")),
50  _mesh(*getParam<MooseMesh *>("mesh")),
51  _eq(_mesh),
52  _ref_mesh(_mproblem.mesh()),
53  _displacements(getParam<std::vector<std::string>>("displacements")),
54  _geometric_search_data(*this, _mesh)
55 
56 {
57  // Disable refinement/coarsening in EquationSystems::reinit because we already do this ourselves
59 
60  // TODO: Move newAssemblyArray further up to SubProblem so that we can use it here
61  unsigned int n_threads = libMesh::n_threads();
62 
63  _assembly.resize(n_threads);
64  for (const auto nl_sys_num : make_range(_mproblem.numNonlinearSystems()))
65  {
66  _displaced_solver_systems.emplace_back(std::make_unique<DisplacedSystem>(
67  *this,
68  _mproblem,
70  "displaced_" + _mproblem.getNonlinearSystemBase(nl_sys_num).name() + "_" +
71  std::to_string(nl_sys_num),
73  auto & displaced_nl = _displaced_solver_systems.back();
74 
75  for (unsigned int i = 0; i < n_threads; ++i)
76  _assembly[i].emplace_back(std::make_unique<Assembly>(*displaced_nl, i));
77  }
78 
79  _nl_solution.resize(_displaced_solver_systems.size(), nullptr);
80 
82  std::make_unique<DisplacedSystem>(*this,
83  _mproblem,
85  "displaced_" + _mproblem.getAuxiliarySystem().name(),
87 
88  // // Generally speaking, the mesh is prepared for use, and consequently remote elements are deleted
89  // // well before our Problem(s) are constructed. Historically, in MooseMesh we have a bunch of
90  // // needs_prepare type flags that make it so we never call prepare_for_use (and consequently
91  // // delete_remote_elements) again. So the below line, historically, has had no impact. HOWEVER:
92  // // I've added some code in SetupMeshCompleteAction for deleting remote elements post
93  // // EquationSystems::init. If I execute that code without default ghosting, then I get > 40 MOOSE
94  // // test failures, so we clearly have some simulations that are not yet covered properly by
95  // // relationship managers. Until that is resolved, I am going to retain default geometric ghosting
96  // if (!_default_ghosting)
97  // _mesh.getMesh().remove_ghosting_functor(_mesh.getMesh().default_ghosting());
98 
100 
102 }
103 
105 
106 bool
108 {
109  return _mproblem.isTransient();
110 }
111 
112 std::set<dof_id_type> &
114 {
115  return _mproblem.ghostedElems();
116 }
117 
118 void
120  Order order,
121  Order volume_order,
122  Order face_order,
123  SubdomainID block,
124  const bool allow_negative_qweights)
125 {
126  for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
127  for (const auto sys_num : index_range(_assembly[tid]))
128  _assembly[tid][sys_num]->createQRules(
129  type, order, volume_order, face_order, block, allow_negative_qweights);
130 }
131 
132 void
134 {
135  for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
136  for (const auto nl_sys_num : index_range(_assembly[tid]))
137  _assembly[tid][nl_sys_num]->bumpVolumeQRuleOrder(order, block);
138 }
139 
140 void
142 {
143  for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
144  for (const auto nl_sys_num : index_range(_assembly[tid]))
145  _assembly[tid][nl_sys_num]->bumpAllQRuleOrder(order, block);
146 }
147 
148 void
150 {
151  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
152  {
153  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
154  _assembly[tid][nl_sys_num]->init(_mproblem.couplingMatrix(nl_sys_num));
155 
156  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
157  {
158  std::vector<std::pair<unsigned int, unsigned short>> disp_numbers_and_directions;
159  for (const auto direction : index_range(_displacements))
160  {
161  const auto & disp_string = _displacements[direction];
162  const auto & disp_variable = getVariable(tid, disp_string);
163  if (disp_variable.sys().number() == nl_sys_num)
164  disp_numbers_and_directions.push_back(
165  std::make_pair(disp_variable.number(), cast_int<unsigned short>(direction)));
166  }
167  _assembly[tid][nl_sys_num]->assignDisplacements(std::move(disp_numbers_and_directions));
168  }
169  }
170 
171  for (auto & nl : _displaced_solver_systems)
172  {
173  nl->dofMap().attach_extra_send_list_function(&extraSendList, nl.get());
174  nl->preInit();
175  }
176 
177  _displaced_aux->dofMap().attach_extra_send_list_function(&extraSendList, _displaced_aux.get());
178  _displaced_aux->preInit();
179 
180  {
181  TIME_SECTION("eq::init", 2, "Initializing Displaced Equation System");
182  _eq.init();
183  }
184 
185  for (auto & nl : _displaced_solver_systems)
186  nl->postInit();
187  _displaced_aux->postInit();
188 
189  _mesh.meshChanged();
190 
191  if (haveFV())
193 }
194 
195 void
197 {
198 }
199 
200 void
202 {
203  for (const auto nl_sys_num : make_range(_mproblem.numNonlinearSystems()))
204  _displaced_solver_systems[nl_sys_num]->copyTimeIntegrators(
205  _mproblem.getNonlinearSystemBase(nl_sys_num));
206  _displaced_aux->copyTimeIntegrators(_mproblem.getAuxiliarySystem());
207 }
208 
209 void
211 {
212  for (auto & displaced_nl : _displaced_solver_systems)
213  displaced_nl->saveOldSolutions();
214  _displaced_aux->saveOldSolutions();
215 }
216 
217 void
219 {
220  for (auto & displaced_nl : _displaced_solver_systems)
221  displaced_nl->restoreOldSolutions();
222  _displaced_aux->restoreOldSolutions();
223 }
224 
225 void
227 {
228  (*_displaced_aux->sys().solution) = aux_soln;
229  _displaced_aux->update();
230 }
231 
232 void
234 {
235  TIME_SECTION("syncSolutions", 5, "Syncing Displaced Solutions");
236 
237  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
238  {
239  auto & displaced_nl = _displaced_solver_systems[nl_sys_num];
240  mooseAssert(nl_sys_num == displaced_nl->number(),
241  "We should have designed things such that the nl system numbers make their system "
242  "numbering in the EquationSystems object");
243  (*displaced_nl->sys().solution) =
244  *_mproblem.getNonlinearSystemBase(displaced_nl->number()).currentSolution();
245  displaced_nl->update();
246  }
248 }
249 
250 void
252  const std::map<unsigned int, const NumericVector<Number> *> & nl_solns,
253  const NumericVector<Number> & aux_soln)
254 {
255  TIME_SECTION("syncSolutions", 5, "Syncing Displaced Solutions");
256 
257  for (const auto [nl_sys_num, nl_soln] : nl_solns)
258  {
259  (*_displaced_solver_systems[nl_sys_num]->sys().solution) = *nl_soln;
260  _displaced_solver_systems[nl_sys_num]->update();
261  }
262  syncAuxSolution(aux_soln);
263 }
264 
265 void
266 DisplacedProblem::updateMesh(bool mesh_changing)
267 {
268  TIME_SECTION("updateMesh", 3, "Updating Displaced Mesh");
269 
270  // If the mesh is changing, we are probably performing adaptivity. In that case, we do *not* want
271  // to use the undisplaced mesh solution because it may be out-of-sync, whereas our displaced mesh
272  // solution should be in the correct state after getting restricted/prolonged in
273  // EquationSystems::reinit (must have been called before this method)
274  if (!mesh_changing)
275  syncSolutions();
276 
277  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
278  _nl_solution[nl_sys_num] = _displaced_solver_systems[nl_sys_num]->sys().solution.get();
279  _aux_solution = _displaced_aux->sys().solution.get();
280 
281  // If the displaced mesh has been serialized to one processor (as
282  // may have occurred if it was used for Exodus output), then we need
283  // the reference mesh to be also. For that matter, did anyone
284  // somehow serialize the whole mesh? Hopefully not but let's avoid
285  // causing errors if so.
286  if (_mesh.getMesh().is_serial() && !this->refMesh().getMesh().is_serial())
287  this->refMesh().getMesh().allgather();
288 
290  this->refMesh().getMesh().gather_to_zero();
291 
293 
294  // We displace all nodes, not just semilocal nodes, because
295  // parallel-inconsistent mesh geometry makes libMesh cry.
296  NodeRange node_range(_mesh.getMesh().nodes_begin(),
297  _mesh.getMesh().nodes_end(),
298  /*grainsize=*/1);
299 
300  Threads::parallel_reduce(node_range, udmt);
301  // Displacement of the mesh has invalidated the point locator data (e.g. bounding boxes)
303 
304  // The mesh has changed. Face information normals, areas, etc. must be re-calculated
305  if (haveFV())
307 
308  // Update the geometric searches that depend on the displaced mesh. This call can end up running
309  // NearestNodeThread::operator() which has a throw inside of it. We need to catch it and make sure
310  // it's propagated to all processes before updating the point locator because the latter requires
311  // communication
312  try
313  {
314  // We may need to re-run geometric operations like SecondaryNeighborhoodTread if, for instance,
315  // we have performed mesh adaptivity
316  if (mesh_changing)
318  else
320  }
321  catch (MooseException & e)
322  {
324  }
325 
326  if (udmt.hasDisplacement())
328 
329  // The below call will throw an exception on all processes if any of our processes had an
330  // exception above. This exception will be caught higher up the call stack and the error message
331  // will be printed there
332  _mproblem.checkExceptionAndStopSolve(/*print_message=*/false);
333 
334  // Since the Mesh changed, update the PointLocator object used by DiracKernels.
336 }
337 
338 void
339 DisplacedProblem::updateMesh(const std::map<unsigned int, const NumericVector<Number> *> & nl_solns,
340  const NumericVector<Number> & aux_soln)
341 {
342  TIME_SECTION("updateMesh", 3, "Updating Displaced Mesh");
343 
344  syncSolutions(nl_solns, aux_soln);
345 
346  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
347  _nl_solution[nl_sys_num] = _displaced_solver_systems[nl_sys_num]->sys().solution.get();
348  _aux_solution = _displaced_aux->sys().solution.get();
349 
351 
352  // We displace all nodes, not just semilocal nodes, because
353  // parallel-inconsistent mesh geometry makes libMesh cry.
354  NodeRange node_range(_mesh.getMesh().nodes_begin(),
355  _mesh.getMesh().nodes_end(),
356  /*grainsize=*/1);
357 
358  Threads::parallel_reduce(node_range, udmt);
359 
360  // Update the geometric searches that depend on the displaced mesh. This call can end up running
361  // NearestNodeThread::operator() which has a throw inside of it. We need to catch it and make sure
362  // it's propagated to all processes before updating the point locator because the latter requires
363  // communication
364  try
365  {
367  }
368  catch (MooseException & e)
369  {
371  }
372 
373  if (udmt.hasDisplacement())
375 
376  // The below call will throw an exception on all processes if any of our processes had an
377  // exception above. This exception will be caught higher up the call stack and the error message
378  // will be printed there
379  _mproblem.checkExceptionAndStopSolve(/*print_message=*/false);
380 
381  // Since the Mesh changed, update the PointLocator object used by DiracKernels.
383 }
384 
385 TagID
386 DisplacedProblem::addVectorTag(const TagName & tag_name,
387  const Moose::VectorTagType type /* = Moose::VECTOR_TAG_RESIDUAL */)
388 {
389  return _mproblem.addVectorTag(tag_name, type);
390 }
391 
392 const VectorTag &
394 {
395  return _mproblem.getVectorTag(tag_id);
396 }
397 
398 TagID
399 DisplacedProblem::getVectorTagID(const TagName & tag_name) const
400 {
401  return _mproblem.getVectorTagID(tag_name);
402 }
403 
404 TagName
406 {
407  return _mproblem.vectorTagName(tag_id);
408 }
409 
410 bool
412 {
413  return _mproblem.vectorTagExists(tag_id);
414 }
415 
416 bool
417 DisplacedProblem::vectorTagExists(const TagName & tag_name) const
418 {
419  return _mproblem.vectorTagExists(tag_name);
420 }
421 
422 unsigned int
423 DisplacedProblem::numVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
424 {
425  return _mproblem.numVectorTags(type);
426 }
427 
428 const std::vector<VectorTag> &
429 DisplacedProblem::getVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
430 {
431  return _mproblem.getVectorTags(type);
432 }
433 
436 {
437  return _mproblem.vectorTagType(tag_id);
438 }
439 
440 TagID
442 {
443  return _mproblem.addMatrixTag(tag_name);
444 }
445 
446 TagID
447 DisplacedProblem::getMatrixTagID(const TagName & tag_name) const
448 {
449  return _mproblem.getMatrixTagID(tag_name);
450 }
451 
452 TagName
454 {
455  return _mproblem.matrixTagName(tag);
456 }
457 
458 bool
459 DisplacedProblem::matrixTagExists(const TagName & tag_name) const
460 {
461  return _mproblem.matrixTagExists(tag_name);
462 }
463 
464 bool
466 {
467  return _mproblem.matrixTagExists(tag_id);
468 }
469 
470 unsigned int
472 {
473  return _mproblem.numMatrixTags();
474 }
475 
476 bool
477 DisplacedProblem::hasVariable(const std::string & var_name) const
478 {
479  for (auto & nl : _displaced_solver_systems)
480  if (nl->hasVariable(var_name))
481  return true;
482  if (_displaced_aux->hasVariable(var_name))
483  return true;
484 
485  return false;
486 }
487 
490  const std::string & var_name,
491  Moose::VarKindType expected_var_type,
492  Moose::VarFieldType expected_var_field_type) const
493 {
494  return getVariableHelper(tid,
495  var_name,
496  expected_var_type,
497  expected_var_field_type,
499  *_displaced_aux);
500 }
501 
503 DisplacedProblem::getStandardVariable(const THREAD_ID tid, const std::string & var_name)
504 {
505  for (auto & nl : _displaced_solver_systems)
506  if (nl->hasVariable(var_name))
507  return nl->getFieldVariable<Real>(tid, var_name);
508  if (_displaced_aux->hasVariable(var_name))
509  return _displaced_aux->getFieldVariable<Real>(tid, var_name);
510 
511  mooseError("No variable with name '" + var_name + "'");
512 }
513 
515 DisplacedProblem::getActualFieldVariable(const THREAD_ID tid, const std::string & var_name)
516 {
517  for (auto & nl : _displaced_solver_systems)
518  if (nl->hasVariable(var_name))
519  return nl->getActualFieldVariable<Real>(tid, var_name);
520  if (_displaced_aux->hasVariable(var_name))
521  return _displaced_aux->getActualFieldVariable<Real>(tid, var_name);
522 
523  mooseError("No variable with name '" + var_name + "'");
524 }
525 
527 DisplacedProblem::getVectorVariable(const THREAD_ID tid, const std::string & var_name)
528 {
529  for (auto & nl : _displaced_solver_systems)
530  if (nl->hasVariable(var_name))
531  return nl->getFieldVariable<RealVectorValue>(tid, var_name);
532  if (_displaced_aux->hasVariable(var_name))
533  return _displaced_aux->getFieldVariable<RealVectorValue>(tid, var_name);
534 
535  mooseError("No variable with name '" + var_name + "'");
536 }
537 
539 DisplacedProblem::getArrayVariable(const THREAD_ID tid, const std::string & var_name)
540 {
541  for (auto & nl : _displaced_solver_systems)
542  if (nl->hasVariable(var_name))
543  return nl->getFieldVariable<RealEigenVector>(tid, var_name);
544  if (_displaced_aux->hasVariable(var_name))
545  return _displaced_aux->getFieldVariable<RealEigenVector>(tid, var_name);
546 
547  mooseError("No variable with name '" + var_name + "'");
548 }
549 
550 bool
551 DisplacedProblem::hasScalarVariable(const std::string & var_name) const
552 {
553  for (auto & nl : _displaced_solver_systems)
554  if (nl->hasScalarVariable(var_name))
555  return true;
556  if (_displaced_aux->hasScalarVariable(var_name))
557  return true;
558 
559  return false;
560 }
561 
563 DisplacedProblem::getScalarVariable(const THREAD_ID tid, const std::string & var_name)
564 {
565  for (auto & nl : _displaced_solver_systems)
566  if (nl->hasScalarVariable(var_name))
567  return nl->getScalarVariable(tid, var_name);
568  if (_displaced_aux->hasScalarVariable(var_name))
569  return _displaced_aux->getScalarVariable(tid, var_name);
570 
571  mooseError("No variable with name '" + var_name + "'");
572 }
573 
574 System &
575 DisplacedProblem::getSystem(const std::string & var_name)
576 {
577  for (const auto sys_num : make_range(_eq.n_systems()))
578  {
579  auto & sys = _eq.get_system(sys_num);
580  if (sys.has_variable(var_name))
581  return sys;
582  }
583 
584  mooseError("Unable to find a system containing the variable " + var_name);
585 }
586 
587 void
588 DisplacedProblem::addVariable(const std::string & var_type,
589  const std::string & name,
590  InputParameters & parameters,
591  const unsigned int nl_system_number)
592 {
593  _displaced_solver_systems[nl_system_number]->addVariable(var_type, name, parameters);
594 }
595 
596 void
597 DisplacedProblem::addAuxVariable(const std::string & var_type,
598  const std::string & name,
599  InputParameters & parameters)
600 {
601  _displaced_aux->addVariable(var_type, name, parameters);
602 }
603 
604 unsigned int
606 {
607  return _mproblem.currentNlSysNum();
608 }
609 
610 unsigned int
612 {
614 }
615 
616 void
617 DisplacedProblem::prepare(const Elem * elem, const THREAD_ID tid)
618 {
619  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
620  {
621  _assembly[tid][nl_sys_num]->reinit(elem);
622  _displaced_solver_systems[nl_sys_num]->prepare(tid);
623  // This method is called outside of residual/Jacobian callbacks during initial condition
624  // evaluation
626  _assembly[tid][nl_sys_num]->prepareJacobianBlock();
627  _assembly[tid][nl_sys_num]->prepareResidual();
628  }
629 
630  _displaced_aux->prepare(tid);
631 }
632 
633 void
635 {
636  _assembly[tid][currentNlSysNum()]->prepareNonlocal();
637 }
638 
639 void
640 DisplacedProblem::prepareFace(const Elem * /*elem*/, const THREAD_ID tid)
641 {
642  for (auto & nl : _displaced_solver_systems)
643  nl->prepareFace(tid, true);
644  _displaced_aux->prepareFace(tid, false);
645 }
646 
647 void
648 DisplacedProblem::prepare(const Elem * elem,
649  unsigned int ivar,
650  unsigned int jvar,
651  const std::vector<dof_id_type> & dof_indices,
652  const THREAD_ID tid)
653 {
654  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
655  {
656  _assembly[tid][nl_sys_num]->reinit(elem);
657  _displaced_solver_systems[nl_sys_num]->prepare(tid);
658  }
659  _displaced_aux->prepare(tid);
660  _assembly[tid][currentNlSysNum()]->prepareBlock(ivar, jvar, dof_indices);
661 }
662 
663 void
665 {
666  SubdomainID did = elem->subdomain_id();
667  for (auto & assembly : _assembly[tid])
669 }
670 
671 void
672 DisplacedProblem::setNeighborSubdomainID(const Elem * elem, unsigned int side, const THREAD_ID tid)
673 {
674  SubdomainID did = elem->neighbor_ptr(side)->subdomain_id();
675  for (auto & assembly : _assembly[tid])
677 }
678 
679 void
681  unsigned int jvar,
682  const std::vector<dof_id_type> & idof_indices,
683  const std::vector<dof_id_type> & jdof_indices,
684  const THREAD_ID tid)
685 {
686  _assembly[tid][currentNlSysNum()]->prepareBlockNonlocal(ivar, jvar, idof_indices, jdof_indices);
687 }
688 
689 void
691 {
692  _assembly[tid][currentNlSysNum()]->prepare();
693 }
694 
695 void
697 {
698  _assembly[tid][currentNlSysNum()]->prepareNeighbor();
699 }
700 
701 bool
703 {
704  std::vector<Point> & points = _dirac_kernel_info.getPoints()[elem].first;
705 
706  unsigned int n_points = points.size();
707 
708  if (n_points)
709  {
710  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
711  {
712  _assembly[tid][nl_sys_num]->reinitAtPhysical(elem, points);
713  _displaced_solver_systems[nl_sys_num]->prepare(tid);
714  }
715  _displaced_aux->prepare(tid);
716 
717  reinitElem(elem, tid);
718  }
719 
720  _assembly[tid][currentNlSysNum()]->prepare();
721 
722  return n_points > 0;
723 }
724 
725 void
727 {
728  for (auto & nl : _displaced_solver_systems)
729  nl->reinitElem(elem, tid);
730  _displaced_aux->reinitElem(elem, tid);
731 }
732 
733 void
735  const std::vector<Point> & phys_points_in_elem,
736  const THREAD_ID tid)
737 {
738  mooseAssert(_mesh.queryElemPtr(elem->id()) == elem,
739  "Are you calling this method with a undisplaced mesh element?");
740 
741  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
742  {
743  _assembly[tid][nl_sys_num]->reinitAtPhysical(elem, phys_points_in_elem);
744  _displaced_solver_systems[nl_sys_num]->prepare(tid);
745  _assembly[tid][nl_sys_num]->prepare();
746  }
747  _displaced_aux->prepare(tid);
748 
749  reinitElem(elem, tid);
750 }
751 
752 void
753 DisplacedProblem::reinitElemFace(const Elem * elem, unsigned int side, const THREAD_ID tid)
754 {
755  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
756  {
757  _assembly[tid][nl_sys_num]->reinit(elem, side);
758  _displaced_solver_systems[nl_sys_num]->reinitElemFace(elem, side, tid);
759  }
760  _displaced_aux->reinitElemFace(elem, side, tid);
761 }
762 
763 void
765 {
766  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
767  {
768  _assembly[tid][nl_sys_num]->reinit(node);
769  _displaced_solver_systems[nl_sys_num]->reinitNode(node, tid);
770  }
771  _displaced_aux->reinitNode(node, tid);
772 }
773 
774 void
776 {
777  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
778  {
779  _assembly[tid][nl_sys_num]->reinit(node);
780  _displaced_solver_systems[nl_sys_num]->reinitNodeFace(node, bnd_id, tid);
781  }
782  _displaced_aux->reinitNodeFace(node, bnd_id, tid);
783 }
784 
785 void
786 DisplacedProblem::reinitNodes(const std::vector<dof_id_type> & nodes, const THREAD_ID tid)
787 {
788  for (auto & nl : _displaced_solver_systems)
789  nl->reinitNodes(nodes, tid);
790  _displaced_aux->reinitNodes(nodes, tid);
791 }
792 
793 void
794 DisplacedProblem::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes, const THREAD_ID tid)
795 {
796  for (auto & nl : _displaced_solver_systems)
797  nl->reinitNodesNeighbor(nodes, tid);
798  _displaced_aux->reinitNodesNeighbor(nodes, tid);
799 }
800 
801 void
802 DisplacedProblem::reinitNeighbor(const Elem * elem, unsigned int side, const THREAD_ID tid)
803 {
804  reinitNeighbor(elem, side, tid, nullptr);
805 }
806 
807 void
809  unsigned int side,
810  const THREAD_ID tid,
811  const std::vector<Point> * neighbor_reference_points)
812 {
813  setNeighborSubdomainID(elem, side, tid);
814 
815  const Elem * neighbor = elem->neighbor_ptr(side);
816  unsigned int neighbor_side = neighbor->which_neighbor_am_i(elem);
817 
818  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
819  {
820  _assembly[tid][nl_sys_num]->reinitElemAndNeighbor(
821  elem, side, neighbor, neighbor_side, neighbor_reference_points);
822  _displaced_solver_systems[nl_sys_num]->prepareNeighbor(tid);
823  // Called during stateful material property evaluation outside of solve
824  _assembly[tid][nl_sys_num]->prepareNeighbor();
825  }
826  _displaced_aux->prepareNeighbor(tid);
827 
828  for (auto & nl : _displaced_solver_systems)
829  {
830  nl->reinitElemFace(elem, side, tid);
831  nl->reinitNeighborFace(neighbor, neighbor_side, tid);
832  }
833  _displaced_aux->reinitElemFace(elem, side, tid);
834  _displaced_aux->reinitNeighborFace(neighbor, neighbor_side, tid);
835 }
836 
837 void
839  unsigned int neighbor_side,
840  const std::vector<Point> & physical_points,
841  const THREAD_ID tid)
842 {
843  mooseAssert(_mesh.queryElemPtr(neighbor->id()) == neighbor,
844  "Are you calling this method with a undisplaced mesh element?");
845 
846  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
847  {
848  // Reinit shape functions
849  _assembly[tid][nl_sys_num]->reinitNeighborAtPhysical(neighbor, neighbor_side, physical_points);
850 
851  // Set the neighbor dof indices
852  _displaced_solver_systems[nl_sys_num]->prepareNeighbor(tid);
853  }
854  _displaced_aux->prepareNeighbor(tid);
855 
857 
858  // Compute values at the points
859  for (auto & nl : _displaced_solver_systems)
860  nl->reinitNeighborFace(neighbor, neighbor_side, tid);
861  _displaced_aux->reinitNeighborFace(neighbor, neighbor_side, tid);
862 }
863 
864 void
866  const std::vector<Point> & physical_points,
867  const THREAD_ID tid)
868 {
869  mooseAssert(_mesh.queryElemPtr(neighbor->id()) == neighbor,
870  "Are you calling this method with a undisplaced mesh element?");
871 
872  for (const auto nl_sys_num : index_range(_displaced_solver_systems))
873  {
874  // Reinit shape functions
875  _assembly[tid][nl_sys_num]->reinitNeighborAtPhysical(neighbor, physical_points);
876 
877  // Set the neighbor dof indices
878  _displaced_solver_systems[nl_sys_num]->prepareNeighbor(tid);
879  }
880  _displaced_aux->prepareNeighbor(tid);
881 
883 
884  // Compute values at the points
885  for (auto & nl : _displaced_solver_systems)
886  nl->reinitNeighbor(neighbor, tid);
887  _displaced_aux->reinitNeighbor(neighbor, tid);
888 }
889 
890 void
892  unsigned int side,
893  const THREAD_ID tid)
894 {
895  reinitNeighbor(elem, side, tid);
896 
897  const Elem * lower_d_elem = _mesh.getLowerDElem(elem, side);
898  if (lower_d_elem && _mesh.interiorLowerDBlocks().count(lower_d_elem->subdomain_id()) > 0)
899  reinitLowerDElem(lower_d_elem, tid);
900  else
901  {
902  // with mesh refinement, lower-dimensional element might be defined on neighbor side
903  auto & neighbor = _assembly[tid][currentNlSysNum()]->neighbor();
904  auto & neighbor_side = _assembly[tid][currentNlSysNum()]->neighborSide();
905  const Elem * lower_d_elem_neighbor = _mesh.getLowerDElem(neighbor, neighbor_side);
906  if (lower_d_elem_neighbor &&
907  _mesh.interiorLowerDBlocks().count(lower_d_elem_neighbor->subdomain_id()) > 0)
908  {
909  auto qps = _assembly[tid][currentNlSysNum()]->qPointsFaceNeighbor().stdVector();
910  std::vector<Point> reference_points;
911  FEMap::inverse_map(
912  lower_d_elem_neighbor->dim(), lower_d_elem_neighbor, qps, reference_points);
913  reinitLowerDElem(lower_d_elem_neighbor, tid, &qps);
914  }
915  }
916 }
917 
918 void
920  bool reinit_for_derivative_reordering /*=false*/)
921 {
922  for (auto & nl : _displaced_solver_systems)
923  nl->reinitScalars(tid, reinit_for_derivative_reordering);
924  _displaced_aux->reinitScalars(tid, reinit_for_derivative_reordering);
925 }
926 
927 void
929 {
930  _assembly[tid][currentNlSysNum()]->prepareOffDiagScalar();
931 }
932 
933 void
934 DisplacedProblem::getDiracElements(std::set<const Elem *> & elems)
935 {
937 }
938 
939 void
941 {
943 }
944 
945 void
947 {
948  _assembly[tid][currentNlSysNum()]->addResidual(Assembly::GlobalDataKey{},
950 }
951 
952 void
954 {
955  _assembly[tid][currentNlSysNum()]->addResidualNeighbor(Assembly::GlobalDataKey{},
957 }
958 
959 void
961 {
962  _assembly[tid][currentNlSysNum()]->addResidualLower(Assembly::GlobalDataKey{},
964 }
965 
966 void
968 {
969  if (_displaced_solver_systems[currentNlSysNum()]->hasVector(
970  _displaced_solver_systems[currentNlSysNum()]->timeVectorTag()))
971  _assembly[tid][currentNlSysNum()]->addCachedResidualDirectly(
972  residual,
975 
976  if (_displaced_solver_systems[currentNlSysNum()]->hasVector(
977  _displaced_solver_systems[currentNlSysNum()]->nonTimeVectorTag()))
978  _assembly[tid][currentNlSysNum()]->addCachedResidualDirectly(
979  residual,
981  getVectorTag(_displaced_solver_systems[currentNlSysNum()]->nonTimeVectorTag()));
982 
983  // We do this because by adding the cached residual directly, we cannot ensure that all of the
984  // cached residuals are emptied after only the two add calls above
985  _assembly[tid][currentNlSysNum()]->clearCachedResiduals(Assembly::GlobalDataKey{});
986 }
987 
988 void
990 {
991  _assembly[tid][currentNlSysNum()]->setResidual(
992  residual,
994  getVectorTag(_displaced_solver_systems[currentNlSysNum()]->residualVectorTag()));
995 }
996 
997 void
999 {
1000  _assembly[tid][currentNlSysNum()]->setResidualNeighbor(
1001  residual,
1003  getVectorTag(_displaced_solver_systems[currentNlSysNum()]->residualVectorTag()));
1004 }
1005 
1006 void
1008 {
1009  _assembly[tid][currentNlSysNum()]->addJacobian(Assembly::GlobalDataKey{});
1010 }
1011 
1012 void
1014 {
1015  _assembly[tid][currentNlSysNum()]->addJacobianNonlocal(Assembly::GlobalDataKey{});
1016 }
1017 
1018 void
1020 {
1021  _assembly[tid][currentNlSysNum()]->addJacobianNeighbor(Assembly::GlobalDataKey{});
1022 }
1023 
1024 void
1026 {
1027  _assembly[tid][currentNlSysNum()]->addJacobianNeighborLowerD(Assembly::GlobalDataKey{});
1028 }
1029 
1030 void
1032 {
1033  _assembly[tid][currentNlSysNum()]->addJacobianLowerD(Assembly::GlobalDataKey{});
1034 }
1035 
1036 void
1038 {
1039  _assembly[tid][currentNlSysNum()]->cacheJacobianNonlocal(Assembly::GlobalDataKey{});
1040 }
1041 
1042 void
1044  unsigned int ivar,
1045  unsigned int jvar,
1046  const DofMap & dof_map,
1047  std::vector<dof_id_type> & dof_indices,
1048  const std::set<TagID> & tags,
1049  const THREAD_ID tid)
1050 {
1051  _assembly[tid][currentNlSysNum()]->addJacobianBlockTags(
1052  jacobian, ivar, jvar, dof_map, dof_indices, Assembly::GlobalDataKey{}, tags);
1053 }
1054 
1055 void
1057  unsigned int ivar,
1058  unsigned int jvar,
1059  const DofMap & dof_map,
1060  const std::vector<dof_id_type> & idof_indices,
1061  const std::vector<dof_id_type> & jdof_indices,
1062  const std::set<TagID> & tags,
1063  const THREAD_ID tid)
1064 {
1065  _assembly[tid][currentNlSysNum()]->addJacobianBlockNonlocalTags(
1066  jacobian, ivar, jvar, dof_map, idof_indices, jdof_indices, Assembly::GlobalDataKey{}, tags);
1067 }
1068 
1069 void
1071  unsigned int ivar,
1072  unsigned int jvar,
1073  const DofMap & dof_map,
1074  std::vector<dof_id_type> & dof_indices,
1075  std::vector<dof_id_type> & neighbor_dof_indices,
1076  const std::set<TagID> & tags,
1077  const THREAD_ID tid)
1078 {
1079  _assembly[tid][currentNlSysNum()]->addJacobianNeighborTags(jacobian,
1080  ivar,
1081  jvar,
1082  dof_map,
1083  dof_indices,
1084  neighbor_dof_indices,
1086  tags);
1087 }
1088 
1089 void
1090 DisplacedProblem::prepareShapes(unsigned int var, const THREAD_ID tid)
1091 {
1092  _assembly[tid][currentNlSysNum()]->copyShapes(var);
1093 }
1094 
1095 void
1097 {
1098  _assembly[tid][currentNlSysNum()]->copyFaceShapes(var);
1099 }
1100 
1101 void
1103 {
1104  _assembly[tid][currentNlSysNum()]->copyNeighborShapes(var);
1105 }
1106 
1107 void
1109 {
1110  TIME_SECTION("updateGeometricSearch", 3, "Updating Displaced GeometricSearch");
1111 
1113 }
1114 
1115 void
1116 DisplacedProblem::meshChanged(const bool contract_mesh, const bool clean_refinement_flags)
1117 {
1118  // The mesh changed. The displaced equations system object only holds Systems, so calling
1119  // EquationSystems::reinit only prolongs/restricts the solution vectors, which is something that
1120  // needs to happen for every step of mesh adaptivity.
1121  _eq.reinit();
1122  if (contract_mesh)
1123  // Once vectors are restricted, we can delete children of coarsened elements
1124  _mesh.getMesh().contract();
1125  if (clean_refinement_flags)
1126  {
1127  // Finally clean refinement flags so that if someone tries to project vectors again without
1128  // an intervening mesh refinement to clean flags they won't run into trouble
1129  MeshRefinement refinement(_mesh.getMesh());
1130  refinement.clean_refinement_flags();
1131  }
1132 
1133  // Since the mesh has changed, we need to make sure that we update any of our
1134  // MOOSE-system specific data.
1135  for (auto & nl : _displaced_solver_systems)
1136  nl->reinit();
1137  _displaced_aux->reinit();
1138 
1139  // We've performed some mesh adaptivity. We need to
1140  // clear any quadrature nodes such that when we build the boundary node lists in
1141  // MooseMesh::meshChanged we don't have any extraneous extra boundary nodes lying around
1143 
1144  _mesh.meshChanged();
1145 
1146  // Before performing mesh adaptivity we un-displaced the mesh. We need to re-displace the mesh and
1147  // then reinitialize GeometricSearchData such that we have all the correct geometric information
1148  // for the changed mesh
1149  updateMesh(/*mesh_changing=*/true);
1150 }
1151 
1152 void
1154 {
1155  _mproblem.addGhostedElem(elem_id);
1156 }
1157 
1158 void
1160 {
1161  _mproblem.addGhostedBoundary(boundary_id);
1162 }
1163 
1164 void
1166 {
1168 }
1169 
1170 MooseMesh &
1172 {
1173  return _ref_mesh;
1174 }
1175 
1176 bool
1177 DisplacedProblem::solverSystemConverged(const unsigned int sys_num)
1178 {
1179  return _mproblem.converged(sys_num);
1180 }
1181 
1182 bool
1183 DisplacedProblem::computingPreSMOResidual(const unsigned int nl_sys_num) const
1184 {
1185  return _mproblem.computingPreSMOResidual(nl_sys_num);
1186 }
1187 
1188 void
1190 {
1191 }
1192 
1193 void
1195 {
1196 }
1197 
1198 void
1200 {
1201  // If undisplaceMesh() is called during initial adaptivity, it is
1202  // not valid to call _mesh.getActiveSemiLocalNodeRange() since it is
1203  // not set up yet. So we are creating the Range by hand.
1204  //
1205  // We must undisplace *all* our nodes to the _ref_mesh
1206  // configuration, not just the local ones, since the partitioners
1207  // require this. We are using the GRAIN_SIZE=1 from MooseMesh.C,
1208  // not sure how this value was decided upon.
1209  //
1210  // (DRG: The grainsize parameter is ultimately passed to TBB to help
1211  // it choose how to split up the range. A grainsize of 1 says "split
1212  // it as much as you want". Years ago I experimentally found that it
1213  // didn't matter much and that using 1 was fine.)
1214  //
1215  // Note: we don't have to invalidate/update as much stuff as
1216  // DisplacedProblem::updateMesh() does, since this will be handled
1217  // by a later call to updateMesh().
1218  NodeRange node_range(_mesh.getMesh().nodes_begin(),
1219  _mesh.getMesh().nodes_end(),
1220  /*grainsize=*/1);
1221 
1222  ResetDisplacedMeshThread rdmt(_mproblem, *this);
1223 
1224  // Undisplace the mesh using threads.
1225  Threads::parallel_reduce(node_range, rdmt);
1226 }
1227 
1228 LineSearch *
1230 {
1231  return _mproblem.getLineSearch();
1232 }
1233 
1234 const CouplingMatrix *
1235 DisplacedProblem::couplingMatrix(const unsigned int nl_sys_num) const
1236 {
1237  return _mproblem.couplingMatrix(nl_sys_num);
1238 }
1239 
1240 bool
1242 {
1244 }
1245 
1246 bool
1248 {
1250 }
1251 
1252 void
1254 {
1256 
1257  for (auto & nl : _displaced_solver_systems)
1258  nl->initialSetup();
1259  _displaced_aux->initialSetup();
1260 }
1261 
1262 void
1264 {
1266 
1267  for (auto & nl : _displaced_solver_systems)
1268  nl->timestepSetup();
1269  _displaced_aux->timestepSetup();
1270 }
1271 
1272 void
1274 {
1275  SubProblem::customSetup(exec_type);
1276 
1277  for (auto & nl : _displaced_solver_systems)
1278  nl->customSetup(exec_type);
1279  _displaced_aux->customSetup(exec_type);
1280 }
1281 
1282 void
1284 {
1286 
1287  for (auto & nl : _displaced_solver_systems)
1288  nl->residualSetup();
1289  _displaced_aux->residualSetup();
1290 }
1291 
1292 void
1294 {
1296 
1297  for (auto & nl : _displaced_solver_systems)
1298  nl->jacobianSetup();
1299  _displaced_aux->jacobianSetup();
1300 }
1301 
1302 void
1303 DisplacedProblem::haveADObjects(const bool have_ad_objects)
1304 {
1305  _have_ad_objects = have_ad_objects;
1306  _mproblem.SubProblem::haveADObjects(have_ad_objects);
1307 }
1308 
1309 std::pair<bool, unsigned int>
1310 DisplacedProblem::determineSolverSystem(const std::string & var_name,
1311  const bool error_if_not_found) const
1312 {
1313  return _mproblem.determineSolverSystem(var_name, error_if_not_found);
1314 }
1315 
1316 Assembly &
1317 DisplacedProblem::assembly(const THREAD_ID tid, const unsigned int sys_num)
1318 {
1319  mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
1320  mooseAssert(sys_num < _assembly[tid].size(),
1321  "System number larger than the assembly container size");
1322  return *_assembly[tid][sys_num];
1323 }
1324 
1325 const Assembly &
1326 DisplacedProblem::assembly(const THREAD_ID tid, const unsigned int sys_num) const
1327 {
1328  mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
1329  mooseAssert(sys_num < _assembly[tid].size(),
1330  "System number larger than the assembly container size");
1331  return *_assembly[tid][sys_num];
1332 }
1333 
1334 std::size_t
1336 {
1337  return _mproblem.numNonlinearSystems();
1338 }
1339 
1340 std::size_t
1342 {
1343  return _mproblem.numLinearSystems();
1344 }
1345 
1346 std::size_t
1348 {
1349  return _mproblem.numSolverSystems();
1350 }
1351 
1352 const std::vector<VectorTag> &
1354 {
1356 }
1357 
1358 bool
1360 {
1362 }
1363 
1364 bool
1366 {
1368 }
1369 
1370 void
1372 {
1373  _mproblem.needFV();
1374 }
1375 
1376 bool
1378 {
1379  return _mproblem.haveFV();
1380 }
1381 
1382 bool
1384 {
1385  return _mproblem.hasNonlocalCoupling();
1386 }
1387 
1388 unsigned int
1389 DisplacedProblem::nlSysNum(const NonlinearSystemName & nl_sys_name) const
1390 {
1391  return _mproblem.nlSysNum(nl_sys_name);
1392 }
1393 
1394 unsigned int
1395 DisplacedProblem::linearSysNum(const LinearSystemName & sys_name) const
1396 {
1397  return _mproblem.linearSysNum(sys_name);
1398 }
1399 
1400 unsigned int
1401 DisplacedProblem::solverSysNum(const SolverSystemName & sys_name) const
1402 {
1403  return _mproblem.solverSysNum(sys_name);
1404 }
1405 
1408 {
1410 }
1411 
1412 bool
1414 {
1416 }
1417 
1420  : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(fe_problem),
1421  _displaced_problem(displaced_problem),
1422  _ref_mesh(_displaced_problem.refMesh()),
1423  _nl_soln(_displaced_problem._nl_solution),
1424  _aux_soln(*_displaced_problem._aux_solution),
1425  _has_displacement(false)
1426 {
1427  this->init();
1428 }
1429 
1432  : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(x, split),
1433  _displaced_problem(x._displaced_problem),
1434  _ref_mesh(x._ref_mesh),
1435  _nl_soln(x._nl_soln),
1436  _aux_soln(x._aux_soln),
1437  _sys_to_nonghost_and_ghost_soln(x._sys_to_nonghost_and_ghost_soln),
1438  _sys_to_var_num_and_direction(x._sys_to_var_num_and_direction),
1439  _has_displacement(x._has_displacement)
1440 {
1441 }
1442 
1443 void
1445 {
1446  std::vector<std::string> & displacement_variables = _displaced_problem._displacements;
1447  unsigned int num_displacements = displacement_variables.size();
1448  auto & es = _displaced_problem.es();
1449 
1450  _sys_to_var_num_and_direction.clear();
1451  _sys_to_nonghost_and_ghost_soln.clear();
1452 
1453  for (unsigned int i = 0; i < num_displacements; i++)
1454  {
1455  std::string displacement_name = displacement_variables[i];
1456 
1457  for (const auto sys_num : make_range(es.n_systems()))
1458  {
1459  auto & sys = es.get_system(sys_num);
1460  if (sys.has_variable(displacement_name))
1461  {
1462  auto & val = _sys_to_var_num_and_direction[sys.number()];
1463  val.first.push_back(sys.variable_number(displacement_name));
1464  val.second.push_back(i);
1465  break;
1466  }
1467  }
1468  }
1469 
1470  for (const auto & pr : _sys_to_var_num_and_direction)
1471  {
1472  auto & sys = es.get_system(pr.first);
1473  mooseAssert(sys.number() <= _nl_soln.size(),
1474  "The system number should always be less than or equal to the number of nonlinear "
1475  "systems. If it is equal, then this system is the auxiliary system");
1476  const NumericVector<Number> * const nonghost_soln =
1477  sys.number() < _nl_soln.size() ? _nl_soln[sys.number()] : &_aux_soln;
1478  _sys_to_nonghost_and_ghost_soln.emplace(
1479  sys.number(),
1480  std::make_pair(nonghost_soln,
1481  NumericVector<Number>::build(nonghost_soln->comm()).release()));
1482  }
1483 
1484  ConstNodeRange node_range(_ref_mesh.getMesh().nodes_begin(), _ref_mesh.getMesh().nodes_end());
1485 
1486  for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
1487  {
1488  auto & sys = es.get_system(sys_num);
1489  AllNodesSendListThread send_list(
1490  this->_fe_problem, _ref_mesh, var_num_and_direction.first, sys);
1491  Threads::parallel_reduce(node_range, send_list);
1492  send_list.unique();
1493  auto & [soln, ghost_soln] = libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num);
1494  ghost_soln->init(
1495  soln->size(), soln->local_size(), send_list.send_list(), true, libMesh::GHOSTED);
1496  soln->localize(*ghost_soln, send_list.send_list());
1497  }
1498 
1499  _has_displacement = false;
1500 }
1501 
1502 void
1504 {
1505  Node & displaced_node = *(*nd);
1506 
1507  Node & reference_node = _ref_mesh.nodeRef(displaced_node.id());
1508 
1509  for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
1510  {
1511  auto & var_numbers = var_num_and_direction.first;
1512  auto & directions = var_num_and_direction.second;
1513  for (const auto i : index_range(var_numbers))
1514  {
1515  const auto direction = directions[i];
1516  if (reference_node.n_dofs(sys_num, var_numbers[i]) > 0)
1517  {
1518  Real coord = reference_node(direction) +
1519  (*libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num).second)(
1520  reference_node.dof_number(sys_num, var_numbers[i], 0));
1521  if (displaced_node(direction) != coord)
1522  {
1523  displaced_node(direction) = coord;
1524  _has_displacement = true;
1525  }
1526  }
1527  }
1528  }
1529 }
virtual LineSearch * getLineSearch() override
VarFieldType
Definition: MooseTypes.h:721
GeometricSearchData _geometric_search_data
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:203
virtual void reinitNodesNeighbor(const std::vector< dof_id_type > &nodes, const THREAD_ID tid) override
virtual void addGhostedElem(dof_id_type elem_id) override
Will make sure that all dofs connected to elem_id are ghosted to this processor.
friend class UpdateDisplacedMeshThread
bool _have_ad_objects
AD flag indicating whether any AD objects have been added.
Definition: SubProblem.h:1114
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
virtual System & getSystem(const std::string &var_name) override
Returns the equation system containing the variable provided.
virtual void reinitNode(const Node *node, const THREAD_ID tid) override
Order
MooseVariableFieldBase & getVariableHelper(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type, Moose::VarFieldType expected_var_field_type, const std::vector< T > &nls, const SystemBase &aux) const
Helper function called by getVariable that handles the logic for checking whether Variables of the re...
virtual void addGhostedElem(dof_id_type elem_id) override
Will make sure that all dofs connected to elem_id are ghosted to this processor.
virtual void saveOldSolutions()
Allocate vectors and save old solutions into them.
unsigned int n_systems() const
virtual const char * what() const
Get out the error message.
unsigned int n_threads()
void undisplaceMesh()
Resets the displaced mesh to the reference mesh.
const std::set< SubdomainID > & interiorLowerDBlocks() const
Definition: MooseMesh.h:1403
std::shared_ptr< DisplacedProblem > displaced_problem
virtual void reinitLowerDElem(const Elem *lower_d_elem, const THREAD_ID tid, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)
Definition: SubProblem.C:957
virtual bool hasNonlocalCoupling() const override
Whether the simulation has active nonlocal coupling which should be accounted for in the Jacobian...
virtual void checkExceptionAndStopSolve(bool print_message=true)
Check to see if an exception has occurred on any processor and, if possible, force the solve to fail...
virtual void meshDisplaced()
Update data after a mesh displaced.
Keeps track of stuff related to assembling.
Definition: Assembly.h:101
void setCoordData(const MooseMesh &other_mesh)
Set the coordinate system data to that of other_mesh.
Definition: MooseMesh.C:4291
virtual void addAuxVariable(const std::string &var_type, const std::string &name, InputParameters &parameters)
unsigned int TagID
Definition: MooseTypes.h:210
virtual std::size_t numNonlinearSystems() const override
virtual MooseVariableFieldBase & getActualFieldVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested MooseVariableField which may be in any system...
virtual bool haveFV() const override
returns true if this problem includes/needs finite volume functionality.
virtual void residualSetup() override
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition: FEProblem.h:20
virtual void initAdaptivity()
void bumpAllQRuleOrder(Order order, SubdomainID block)
virtual bool safeAccessTaggedVectors() const
Is it safe to access the tagged vectors.
Definition: SubProblem.h:734
virtual void initialSetup() override
virtual bool computingPreSMOResidual(const unsigned int nl_sys_num) const override
Returns true if the problem is in the process of computing it&#39;s initial residual. ...
virtual std::pair< bool, unsigned int > determineSolverSystem(const std::string &var_name, bool error_if_not_found=false) const override
Determine what solver system the provided variable name lies in.
virtual void addJacobianNeighborLowerD(const THREAD_ID tid) override
virtual void needFV() override
marks this problem as including/needing finite volume functionality.
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL) override
Create a Tag.
const Elem * getLowerDElem(const Elem *, unsigned short int) const
Returns a const pointer to a lower dimensional element that corresponds to a side of a higher dimensi...
Definition: MooseMesh.C:1698
virtual bool checkNonlocalCouplingRequirement() const override
virtual void prepareShapes(unsigned int var, const THREAD_ID tid) override
virtual void allgather()
FEProblemBase & _mproblem
virtual numeric_index_type size() const=0
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
Create a Tag.
Definition: SubProblem.C:92
virtual unsigned int currentLinearSysNum() const override
virtual void prepareNeighborShapes(unsigned int var, const THREAD_ID tid) override
virtual void createQRules(QuadratureType type, Order order, Order volume_order, Order face_order, SubdomainID block, bool allow_negative_qweights=true)
virtual void reinitNodes(const std::vector< dof_id_type > &nodes, const THREAD_ID tid) override
virtual void residualSetup()
Definition: SubProblem.C:1201
virtual EquationSystems & es() override
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 bool haveFV() const override
returns true if this problem includes/needs finite volume functionality.
virtual bool safeAccessTaggedMatrices() const override
Is it safe to access the tagged matrices.
virtual bool hasScalarVariable(const std::string &var_name) const override
Returns a Boolean indicating whether any system contains a variable with the name provided...
MeshBase & mesh
const NumericVector< Number > *const & currentSolution() const override
The solution vector that is currently being operated on.
virtual void prepareAssemblyNeighbor(const THREAD_ID tid)
virtual void gather_to_zero()
virtual void addGhostedBoundary(BoundaryID boundary_id) override
Will make sure that all necessary elements from boundary_id are ghosted to this processor.
virtual const std::vector< VectorTag > & currentResidualVectorTags() const override
Return the residual vector tags we are currently computing.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
QuadratureType
UpdateDisplacedMeshThread(FEProblemBase &fe_problem, DisplacedProblem &displaced_problem)
bool hasDisplacement()
Whether the displaced mesh is modified by the latest call to operator()
virtual TagName vectorTagName(const TagID tag_id) const override
Retrieve the name associated with a TagID.
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual void addJacobianLowerD(const THREAD_ID tid) override
virtual TagID getMatrixTagID(const TagName &tag_name) const override
Get a TagID from a TagName.
virtual void jacobianSetup()
Definition: SubProblem.C:1209
virtual void timestepSetup() override
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
void computingScalingJacobian(bool computing_scaling_jacobian)
Setter for whether we&#39;re computing the scaling jacobian.
const T_sys & get_system(std::string_view name) const
virtual unsigned int numVectorTags(const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const override
The total number of tags, which can be limited to the tag type.
virtual unsigned int nlSysNum(const NonlinearSystemName &nl_sys_name) const override
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual std::size_t numSolverSystems() const override
registerMooseObject("MooseApp", DisplacedProblem)
virtual const Node & nodeRef(const dof_id_type i) const
Definition: MooseMesh.C:831
virtual void onTimestepBegin() override
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) override
std::vector< std::unique_ptr< DisplacedSystem > > _displaced_solver_systems
void syncSolutions()
Copy the solutions on the undisplaced systems to the displaced systems.
virtual void prepareBlockNonlocal(unsigned int ivar, unsigned int jvar, const std::vector< dof_id_type > &idof_indices, const std::vector< dof_id_type > &jdof_indices, const THREAD_ID tid)
virtual Elem * queryElemPtr(const dof_id_type i)
Definition: MooseMesh.C:3120
virtual std::set< dof_id_type > & ghostedElems() override
Return the list of elements that should have their DoFs ghosted to this processor.
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid) override
virtual void reinitNeighbor(const Elem *elem, unsigned int side, const THREAD_ID tid) override
virtual bool is_serial_on_zero() const
virtual MooseVariable & getStandardVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested MooseVariable which may be in any system.
const libMesh::CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const override
The coupling matrix defining what blocks exist in the preconditioning matrix.
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
virtual bool computingPreSMOResidual(const unsigned int nl_sys_num) const override
Returns true if the problem is in the process of computing it&#39;s initial residual. ...
void update()
Update the system (doing libMesh magic)
Definition: SystemBase.C:1245
std::vector< std::vector< std::unique_ptr< Assembly > > > _assembly
DisplacedProblem(DisplacedProblem &&)=delete
virtual bool solverSystemConverged(const unsigned int solver_sys_num) override
virtual const std::string & name() const
Definition: SystemBase.C:1330
virtual void customSetup(const ExecFlagType &exec_type)
Definition: SubProblem.C:1193
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
bool automaticScaling() const
Automatic scaling getter.
Definition: SubProblem.C:1162
bool hasJacobian() const
Returns _has_jacobian.
EquationSystems _eq
virtual bool is_serial() const
virtual unsigned int currentNlSysNum() const override
virtual const libMesh::CouplingMatrix & nonlocalCouplingMatrix(const unsigned i) const override
MultiPointMap & getPoints()
Returns a writeable reference to the _points container.
void clearQuadratureNodes()
Clear out any existing quadrature nodes.
Definition: MooseMesh.C:1677
dof_id_type id() const
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3443
std::vector< const NumericVector< Number > * > _nl_solution
The nonlinear system solutions.
virtual std::pair< bool, unsigned int > determineSolverSystem(const std::string &var_name, bool error_if_not_found=false) const override
MooseMesh & _ref_mesh
reference mesh
virtual bool computingScalingResidual() const override final
Getter for whether we&#39;re computing the scaling residual.
virtual TagID getMatrixTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:342
void extraSendList(std::vector< dof_id_type > &send_list, void *context)
///< Type of coordinate system
Definition: SystemBase.C:39
unsigned int which_neighbor_am_i(const Elem *e) const
virtual void reinitElemFace(const Elem *elem, unsigned int side, const THREAD_ID tid) override
std::unique_ptr< DisplacedSystem > _displaced_aux
virtual void addJacobian(const THREAD_ID tid) override
virtual void setResidual(NumericVector< Number > &residual, const THREAD_ID tid) override
boundary_id_type BoundaryID
virtual void clearDiracInfo() override
Gets called before Dirac Kernels are asked to add the points they are supposed to be evaluated in...
bool constJacobian() const
Returns _const_jacobian (whether a MOOSE object has specified that the Jacobian is the same as the pr...
VarKindType
Framework-wide stuff.
Definition: MooseTypes.h:714
void computingScalingResidual(bool computing_scaling_residual)
Setter for whether we&#39;re computing the scaling residual.
virtual void restoreOldSolutions()
Restore old solutions from the backup vectors and deallocate them.
virtual const std::vector< VectorTag > & getVectorTags(const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const override
Return all vector tags, where a tag is represented by a map from name to ID.
virtual TagID addMatrixTag(TagName tag_name)
Create a Tag.
Definition: SubProblem.C:311
virtual void setResidualNeighbor(NumericVector< Number > &residual, const THREAD_ID tid) override
virtual Moose::VectorTagType vectorTagType(const TagID tag_id) const
Definition: SubProblem.C:231
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
virtual bool converged(const unsigned int sys_num)
Eventually we want to convert this virtual over to taking a solver system number argument.
Definition: SubProblem.h:113
void clear_point_locator()
virtual unsigned int currentNlSysNum() const override
virtual unsigned int solverSysNum(const SolverSystemName &sys_name) const override
virtual void reinitNeighborPhys(const Elem *neighbor, unsigned int neighbor_side, const std::vector< Point > &physical_points, const THREAD_ID tid) override
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
void reinit()
Completely redo all geometric search objects.
std::vector< VectorTag > getVectorTags(const std::set< TagID > &tag_ids) const
Definition: SubProblem.C:172
virtual void addVariable(const std::string &var_type, const std::string &name, InputParameters &parameters, unsigned int nl_system_number)
virtual Moose::VectorTagType vectorTagType(const TagID tag_id) const override
virtual void reinitOffDiagScalars(const THREAD_ID tid) override
virtual void addJacobianBlockTags(SparseMatrix< Number > &jacobian, unsigned int ivar, unsigned int jvar, const libMesh::DofMap &dof_map, std::vector< dof_id_type > &dof_indices, const std::set< TagID > &tags, const THREAD_ID tid)
LineSearch * getLineSearch() override
getter for the MOOSE line search
virtual std::set< dof_id_type > & ghostedElems()
Return the list of elements that should have their DoFs ghosted to this processor.
Definition: SubProblem.h:672
std::vector< std::string > _displacements
virtual bool vectorTagExists(const TagID tag_id) const
Check to see if a particular Tag exists.
Definition: SubProblem.h:201
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual const VectorTag & getVectorTag(const TagID tag_id) const override
Get a VectorTag from a TagID.
void clearPoints()
Remove all of the current points and elements.
const NumericVector< Number > * _aux_solution
The auxiliary system solution.
virtual void addResidualLower(const THREAD_ID tid) override
AuxiliarySystem & getAuxiliarySystem()
bool haveADObjects() const
Method for reading wehther we have any ad objects.
Definition: SubProblem.h:771
virtual bool isTransient() const override
GeometricSearchType
Used to select groups of geometric search objects to update.
VectorTagType
Definition: MooseTypes.h:978
virtual void onTimestepEnd() override
virtual std::size_t numNonlinearSystems() const override
virtual const libMesh::CouplingMatrix & nonlocalCouplingMatrix(const unsigned i) const override
virtual void reinitElem(const Elem *elem, const THREAD_ID tid) override
virtual void addCachedResidualDirectly(NumericVector< Number > &residual, const THREAD_ID tid)
virtual void timestepSetup()
Definition: SubProblem.C:1185
virtual unsigned int numMatrixTags() const
The total number of tags.
Definition: SubProblem.h:248
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
tbb::split split
virtual void customSetup(const ExecFlagType &exec_type) override
virtual TagName matrixTagName(TagID tag) override
Retrieve the name associated with a TagID.
const Elem * neighbor_ptr(unsigned int i) const
virtual void reinitNodeFace(const Node *node, BoundaryID bnd_id, const THREAD_ID tid) override
Provides a way for users to bail out of the current solve.
void syncAuxSolution(const NumericVector< Number > &aux_soln)
Copy the provided solution into the displaced auxiliary system.
void setCurrentSubdomainID(SubdomainID i)
set the current subdomain ID
Definition: Assembly.h:385
virtual void initialSetup()
Definition: SubProblem.C:1217
virtual void prepareAssembly(const THREAD_ID tid) override
virtual void prepare(const Elem *elem, const THREAD_ID tid) override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual bool contract()=0
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:78
subdomain_id_type subdomain_id() const
virtual VectorMooseVariable & getVectorVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested VectorMooseVariable which may be in any system...
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
unsigned int solverSysNum(const SolverSystemName &solver_sys_name) const override
vec_type::const_iterator const_iterator
virtual unsigned short dim() const=0
virtual bool matrixTagExists(const TagName &tag_name) const override
Check to see if a particular Tag exists.
virtual bool computingScalingJacobian() const override final
Getter for whether we&#39;re computing the scaling jacobian.
virtual TagID addMatrixTag(TagName tag_name) override
Create a Tag.
virtual void addResidualNeighbor(const THREAD_ID tid) override
void addJacobianBlockNonlocal(SparseMatrix< Number > &jacobian, unsigned int ivar, unsigned int jvar, const libMesh::DofMap &dof_map, const std::vector< dof_id_type > &idof_indices, const std::vector< dof_id_type > &jdof_indices, const std::set< TagID > &tags, const THREAD_ID tid)
virtual void addResidual(const THREAD_ID tid) override
virtual const std::vector< VectorTag > & currentResidualVectorTags() const override
Return the residual vector tags we are currently computing.
const std::vector< dof_id_type > & send_list() const
virtual void cacheJacobianNonlocal(const THREAD_ID tid)
void update(GeometricSearchType type=ALL)
Update all of the search objects.
Class for scalar variables (they are different).
IntRange< T > make_range(T beg, T end)
virtual unsigned int linearSysNum(const LinearSystemName &sys_name) const override
unsigned int linearSysNum(const LinearSystemName &linear_sys_name) const override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
virtual unsigned int numVectorTags(const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const
The total number of tags, which can be limited to the tag type.
Definition: SubProblem.C:195
virtual std::size_t numLinearSystems() const override
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid) override
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const InputParameters & parameters() const
Get the parameters of the object.
virtual void prepareFaceShapes(unsigned int var, const THREAD_ID tid) override
virtual unsigned int numMatrixTags() const override
The total number of tags.
virtual void updateGeomSearch(GeometricSearchData::GeometricSearchType type=GeometricSearchData::ALL) override
virtual void reinitElemNeighborAndLowerD(const Elem *elem, unsigned int side, const THREAD_ID tid) override
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:146
std::set< const Elem * > & getElements()
Returns a writeable reference to the _elements container.
MooseMesh & refMesh()
virtual std::size_t numLinearSystems() const override
virtual bool reinitDirac(const Elem *elem, const THREAD_ID tid) override
Returns true if the Problem has Dirac kernels it needs to compute on elem.
virtual TagName vectorTagName(const TagID tag) const
Retrieve the name associated with a TagID.
Definition: SubProblem.C:221
virtual void setNeighborSubdomainID(const Elem *elem, unsigned int side, const THREAD_ID tid) override
static InputParameters validParams()
Definition: SubProblem.C:36
void automaticScaling(bool automatic_scaling) override
Automatic scaling setter.
virtual ArrayMooseVariable & getArrayVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested ArrayMooseVariable which may be in any system...
virtual void addJacobianNonlocal(const THREAD_ID tid)
virtual bool isTransient() const 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
virtual bool safeAccessTaggedMatrices() const
Is it safe to access the tagged matrices.
Definition: SubProblem.h:731
virtual void updateMesh(bool mesh_changing=false)
Copy the solutions on the undisplaced systems to the displaced systems and reinitialize the geometry ...
virtual bool safeAccessTaggedVectors() const override
Is it safe to access the tagged vectors.
virtual void getDiracElements(std::set< const Elem *> &elems) override
Fills "elems" with the elements that should be looped over for Dirac Kernels.
virtual bool checkNonlocalCouplingRequirement() const override
void meshChanged(bool contract_mesh, bool clean_refinement_flags)
Storage for all of the information pretaining to a vector tag.
Definition: VectorTag.h:17
DiracKernelInfo _dirac_kernel_info
Definition: SubProblem.h:1049
virtual void jacobianSetup() override
void setCurrentNeighborSubdomainID(SubdomainID i)
set the current subdomain ID
Definition: Assembly.h:463
virtual void addGhostedBoundary(BoundaryID boundary_id) override
Will make sure that all necessary elements from boundary_id are ghosted to this processor.
virtual void prepareNonlocal(const THREAD_ID tid)
virtual std::size_t numSolverSystems() const override
virtual unsigned int currentLinearSysNum() const override
virtual void needFV() override
marks this problem as including/needing finite volume functionality.
virtual void prepareFace(const Elem *elem, const THREAD_ID tid) override
virtual void onNode(NodeRange::const_iterator &nd) override
virtual TagID getVectorTagID(const TagName &tag_name) const override
Get a TagID from a TagName.
void addTimeIntegrator()
Get the time integrators from the problem.
virtual const VectorTag & getVectorTag(const TagID tag_id) const
Get a VectorTag from a TagID.
Definition: SubProblem.C:161
void updatePointLocator(const MooseMesh &mesh)
Called during FEProblemBase::meshChanged() to update the PointLocator object used by the DiracKernels...
auto index_range(const T &sizable)
virtual bool hasNonlocalCoupling() const override
Whether the simulation has active nonlocal coupling which should be accounted for in the Jacobian...
virtual const CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const override
The coupling matrix defining what blocks exist in the preconditioning matrix.
virtual bool vectorTagExists(const TagID tag_id) const override
Check to see if a particular Tag exists.
virtual unsigned int nlSysNum(const NonlinearSystemName &nl_sys_name) const override
virtual bool matrixTagExists(const TagName &tag_name) const
Check to see if a particular Tag exists.
Definition: SubProblem.C:328
virtual TagName matrixTagName(TagID tag)
Retrieve the name associated with a TagID.
Definition: SubProblem.C:357
void meshChanged()
Declares that the MooseMesh has changed, invalidates cached data and rebuilds caches.
Definition: MooseMesh.C:879
static InputParameters validParams()
unsigned int THREAD_ID
Definition: MooseTypes.h:209
virtual void ghostGhostedBoundaries() override
Causes the boundaries added using addGhostedBoundary to actually be ghosted.
uint8_t dof_id_type
void bumpVolumeQRuleOrder(Order order, SubdomainID block)
virtual void init() override
virtual void addJacobianNeighbor(const THREAD_ID tid) override
virtual void ghostGhostedBoundaries() override
Causes the boundaries added using addGhostedBoundary to actually be ghosted.
void setupFiniteVolumeMeshData() const
Sets up the additional data needed for finite volume computations.
Definition: MooseMesh.C:4067
Key structure for APIs manipulating global vectors/matrices.
Definition: Assembly.h:815