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