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
29using namespace libMesh;
30
32
35{
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,
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,
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
106bool
111
112std::set<dof_id_type> &
117
118void
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
132void
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
140void
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
148void
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
190
191 if (haveFV())
193}
194
195void
199
200void
202{
203 for (const auto nl_sys_num : make_range(_mproblem.numNonlinearSystems()))
204 _displaced_solver_systems[nl_sys_num]->copyTimeIntegrators(
206 _displaced_aux->copyTimeIntegrators(_mproblem.getAuxiliarySystem());
207}
208
209void
211{
212 for (auto & displaced_nl : _displaced_solver_systems)
213 displaced_nl->saveOldSolutions();
214 _displaced_aux->saveOldSolutions();
215}
216
217void
219{
220 for (auto & displaced_nl : _displaced_solver_systems)
221 displaced_nl->restoreOldSolutions();
222 _displaced_aux->restoreOldSolutions();
223}
224
225void
227{
228 (*_displaced_aux->sys().solution) = aux_soln;
229 _displaced_aux->update();
230}
231
232void
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
250void
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
265void
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)
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
338void
339DisplacedProblem::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
350 UpdateDisplacedMeshThread udmt(_mproblem, *this);
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
385TagID
386DisplacedProblem::addVectorTag(const TagName & tag_name,
387 const Moose::VectorTagType type /* = Moose::VECTOR_TAG_RESIDUAL */)
388{
389 return _mproblem.addVectorTag(tag_name, type);
390}
391
392const VectorTag &
394{
395 return _mproblem.getVectorTag(tag_id);
396}
397
398TagID
399DisplacedProblem::getVectorTagID(const TagName & tag_name) const
400{
401 return _mproblem.getVectorTagID(tag_name);
402}
403
404TagName
406{
407 return _mproblem.vectorTagName(tag_id);
408}
409
410bool
412{
413 return _mproblem.vectorTagExists(tag_id);
414}
415
416bool
417DisplacedProblem::vectorTagExists(const TagName & tag_name) const
418{
419 return _mproblem.vectorTagExists(tag_name);
420}
421
422unsigned int
423DisplacedProblem::numVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
424{
426}
427
428const std::vector<VectorTag> &
429DisplacedProblem::getVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
430{
432}
433
436{
437 return _mproblem.vectorTagType(tag_id);
438}
439
440TagID
442{
443 return _mproblem.addMatrixTag(tag_name);
444}
445
446TagID
447DisplacedProblem::getMatrixTagID(const TagName & tag_name) const
448{
449 return _mproblem.getMatrixTagID(tag_name);
450}
451
452TagName
457
458bool
459DisplacedProblem::matrixTagExists(const TagName & tag_name) const
460{
461 return _mproblem.matrixTagExists(tag_name);
462}
463
464bool
466{
467 return _mproblem.matrixTagExists(tag_id);
468}
469
470unsigned int
475
476bool
477DisplacedProblem::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,
500}
501
503DisplacedProblem::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
515DisplacedProblem::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
527DisplacedProblem::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
539DisplacedProblem::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
550bool
551DisplacedProblem::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
563DisplacedProblem::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
574System &
575DisplacedProblem::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
587void
588DisplacedProblem::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
596void
597DisplacedProblem::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
604unsigned int
609
610unsigned int
615
616void
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
633void
635{
636 _assembly[tid][currentNlSysNum()]->prepareNonlocal();
637}
638
639void
640DisplacedProblem::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
647void
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
663void
665{
666 SubdomainID did = elem->subdomain_id();
667 for (auto & assembly : _assembly[tid])
669}
670
671void
672DisplacedProblem::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
679void
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
689void
691{
692 _assembly[tid][currentNlSysNum()]->prepare();
693}
694
695void
697{
698 _assembly[tid][currentNlSysNum()]->prepareNeighbor();
699}
700
701bool
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
725void
727{
728 for (auto & nl : _displaced_solver_systems)
729 nl->reinitElem(elem, tid);
730 _displaced_aux->reinitElem(elem, tid);
731}
732
733void
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
752void
753DisplacedProblem::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
763void
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
774void
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
785void
786DisplacedProblem::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
793void
794DisplacedProblem::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
801void
802DisplacedProblem::reinitNeighbor(const Elem * elem, unsigned int side, const THREAD_ID tid)
803{
804 reinitNeighbor(elem, side, tid, nullptr);
805}
806
807void
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
837void
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
864void
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
890void
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;
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
918void
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
927void
929{
930 _assembly[tid][currentNlSysNum()]->prepareOffDiagScalar();
931}
932
933void
934DisplacedProblem::getDiracElements(std::set<const Elem *> & elems)
935{
937}
938
939void
944
945void
951
952void
958
959void
965
966void
968{
970 _displaced_solver_systems[currentNlSysNum()]->timeVectorTag()))
971 _assembly[tid][currentNlSysNum()]->addCachedResidualDirectly(
972 residual,
975
977 _displaced_solver_systems[currentNlSysNum()]->nonTimeVectorTag()))
978 _assembly[tid][currentNlSysNum()]->addCachedResidualDirectly(
979 residual,
982
983 std::vector<VectorTag> extra_residual_vector_tags;
984 extra_residual_vector_tags.reserve(currentResidualVectorTags().size());
985 const auto time_tag = _displaced_solver_systems[currentNlSysNum()]->timeVectorTag();
986 const auto non_time_tag = _displaced_solver_systems[currentNlSysNum()]->nonTimeVectorTag();
987 for (const auto & vector_tag : currentResidualVectorTags())
988 if (vector_tag._id != time_tag && vector_tag._id != non_time_tag)
989 extra_residual_vector_tags.push_back(vector_tag);
990
991 // Flush extra vector tag caches (e.g. from extra_vector_tags on NodalConstraints)
992 // to their respective system vectors after the standard TIME/NONTIME caches above.
993 // Without this, NodalConstraint contributions to extra vector tags are silently
994 // discarded by the blanket clearCachedResiduals.
995 _assembly[tid][currentNlSysNum()]->addCachedResiduals(Assembly::GlobalDataKey{},
996 extra_residual_vector_tags);
997
998 // We do this because by adding the cached residual directly, we cannot ensure that all of the
999 // cached residuals are emptied after only the two add calls above
1000 _assembly[tid][currentNlSysNum()]->clearCachedResiduals(Assembly::GlobalDataKey{});
1001}
1002
1003void
1005{
1006 _assembly[tid][currentNlSysNum()]->setResidual(
1007 residual,
1009 getVectorTag(_displaced_solver_systems[currentNlSysNum()]->residualVectorTag()));
1010}
1011
1012void
1014{
1015 _assembly[tid][currentNlSysNum()]->setResidualNeighbor(
1016 residual,
1018 getVectorTag(_displaced_solver_systems[currentNlSysNum()]->residualVectorTag()));
1019}
1020
1021void
1026
1027void
1029{
1030 _assembly[tid][currentNlSysNum()]->addJacobianNonlocal(Assembly::GlobalDataKey{});
1031}
1032
1033void
1035{
1036 _assembly[tid][currentNlSysNum()]->addJacobianNeighbor(Assembly::GlobalDataKey{});
1037}
1038
1039void
1041{
1042 _assembly[tid][currentNlSysNum()]->addJacobianNeighborLowerD(Assembly::GlobalDataKey{});
1043}
1044
1045void
1047{
1048 _assembly[tid][currentNlSysNum()]->addJacobianLowerD(Assembly::GlobalDataKey{});
1049}
1050
1051void
1053{
1054 _assembly[tid][currentNlSysNum()]->cacheJacobianNonlocal(Assembly::GlobalDataKey{});
1055}
1056
1057void
1059 unsigned int ivar,
1060 unsigned int jvar,
1061 const DofMap & dof_map,
1062 std::vector<dof_id_type> & dof_indices,
1063 const std::set<TagID> & tags,
1064 const THREAD_ID tid)
1065{
1066 _assembly[tid][currentNlSysNum()]->addJacobianBlockTags(
1067 jacobian, ivar, jvar, dof_map, dof_indices, Assembly::GlobalDataKey{}, tags);
1068}
1069
1070void
1072 unsigned int ivar,
1073 unsigned int jvar,
1074 const DofMap & dof_map,
1075 const std::vector<dof_id_type> & idof_indices,
1076 const std::vector<dof_id_type> & jdof_indices,
1077 const std::set<TagID> & tags,
1078 const THREAD_ID tid)
1079{
1080 _assembly[tid][currentNlSysNum()]->addJacobianBlockNonlocalTags(
1081 jacobian, ivar, jvar, dof_map, idof_indices, jdof_indices, Assembly::GlobalDataKey{}, tags);
1082}
1083
1084void
1086 unsigned int ivar,
1087 unsigned int jvar,
1088 const DofMap & dof_map,
1089 std::vector<dof_id_type> & dof_indices,
1090 std::vector<dof_id_type> & neighbor_dof_indices,
1091 const std::set<TagID> & tags,
1092 const THREAD_ID tid)
1093{
1094 _assembly[tid][currentNlSysNum()]->addJacobianNeighborTags(jacobian,
1095 ivar,
1096 jvar,
1097 dof_map,
1098 dof_indices,
1099 neighbor_dof_indices,
1101 tags);
1102}
1103
1104void
1105DisplacedProblem::prepareShapes(unsigned int var, const THREAD_ID tid)
1106{
1107 _assembly[tid][currentNlSysNum()]->copyShapes(var);
1108}
1109
1110void
1112{
1113 _assembly[tid][currentNlSysNum()]->copyFaceShapes(var);
1114}
1115
1116void
1118{
1119 _assembly[tid][currentNlSysNum()]->copyNeighborShapes(var);
1120}
1121
1122void
1124{
1125 TIME_SECTION("updateGeometricSearch", 3, "Updating Displaced GeometricSearch");
1126
1128}
1129
1130void
1131DisplacedProblem::meshChanged(const bool contract_mesh, const bool clean_refinement_flags)
1132{
1133 // The mesh changed. The displaced equations system object only holds Systems, so calling
1134 // EquationSystems::reinit only prolongs/restricts the solution vectors, which is something that
1135 // needs to happen for every step of mesh adaptivity.
1136 _eq.reinit();
1137 if (contract_mesh)
1138 // Once vectors are restricted, we can delete children of coarsened elements
1140 if (clean_refinement_flags)
1141 {
1142 // Finally clean refinement flags so that if someone tries to project vectors again without
1143 // an intervening mesh refinement to clean flags they won't run into trouble
1144 MeshRefinement refinement(_mesh.getMesh());
1145 refinement.clean_refinement_flags();
1146 }
1147
1148 // Since the mesh has changed, we need to make sure that we update any of our
1149 // MOOSE-system specific data.
1150 for (auto & nl : _displaced_solver_systems)
1151 nl->reinit();
1152 _displaced_aux->reinit();
1153
1154 // We've performed some mesh adaptivity. We need to
1155 // clear any quadrature nodes such that when we build the boundary node lists in
1156 // MooseMesh::meshChanged we don't have any extraneous extra boundary nodes lying around
1158
1160
1161 // Before performing mesh adaptivity we un-displaced the mesh. We need to re-displace the mesh and
1162 // then reinitialize GeometricSearchData such that we have all the correct geometric information
1163 // for the changed mesh
1164 updateMesh(/*mesh_changing=*/true);
1165}
1166
1167void
1172
1173void
1178
1179void
1184
1185MooseMesh &
1187{
1188 return _ref_mesh;
1189}
1190
1191bool
1193{
1194 return _mproblem.converged(sys_num);
1195}
1196
1197bool
1198DisplacedProblem::computingPreSMOResidual(const unsigned int nl_sys_num) const
1199{
1200 return _mproblem.computingPreSMOResidual(nl_sys_num);
1201}
1202
1203void
1207
1208void
1212
1213void
1215{
1216 // If undisplaceMesh() is called during initial adaptivity, it is
1217 // not valid to call _mesh.getActiveSemiLocalNodeRange() since it is
1218 // not set up yet. So we are creating the Range by hand.
1219 //
1220 // We must undisplace *all* our nodes to the _ref_mesh
1221 // configuration, not just the local ones, since the partitioners
1222 // require this. We are using the GRAIN_SIZE=1 from MooseMesh.C,
1223 // not sure how this value was decided upon.
1224 //
1225 // (DRG: The grainsize parameter is ultimately passed to TBB to help
1226 // it choose how to split up the range. A grainsize of 1 says "split
1227 // it as much as you want". Years ago I experimentally found that it
1228 // didn't matter much and that using 1 was fine.)
1229 //
1230 // Note: we don't have to invalidate/update as much stuff as
1231 // DisplacedProblem::updateMesh() does, since this will be handled
1232 // by a later call to updateMesh().
1233 NodeRange node_range(_mesh.getMesh().nodes_begin(),
1234 _mesh.getMesh().nodes_end(),
1235 /*grainsize=*/1);
1236
1238
1239 // Undisplace the mesh using threads.
1240 Threads::parallel_reduce(node_range, rdmt);
1241}
1242
1243LineSearch *
1248
1249const CouplingMatrix *
1250DisplacedProblem::couplingMatrix(const unsigned int nl_sys_num) const
1251{
1252 return _mproblem.couplingMatrix(nl_sys_num);
1253}
1254
1255bool
1260
1261bool
1266
1267void
1269{
1271
1272 for (auto & nl : _displaced_solver_systems)
1273 nl->initialSetup();
1274 _displaced_aux->initialSetup();
1275}
1276
1277void
1279{
1281
1282 for (auto & nl : _displaced_solver_systems)
1283 nl->timestepSetup();
1284 _displaced_aux->timestepSetup();
1285}
1286
1287void
1289{
1290 SubProblem::customSetup(exec_type);
1291
1292 for (auto & nl : _displaced_solver_systems)
1293 nl->customSetup(exec_type);
1294 _displaced_aux->customSetup(exec_type);
1295}
1296
1297void
1299{
1301
1302 for (auto & nl : _displaced_solver_systems)
1303 nl->residualSetup();
1304 _displaced_aux->residualSetup();
1305}
1306
1307void
1309{
1311
1312 for (auto & nl : _displaced_solver_systems)
1313 nl->jacobianSetup();
1314 _displaced_aux->jacobianSetup();
1315}
1316
1317void
1318DisplacedProblem::haveADObjects(const bool have_ad_objects)
1319{
1320 _have_ad_objects = have_ad_objects;
1321 _mproblem.SubProblem::haveADObjects(have_ad_objects);
1322}
1323
1324std::pair<bool, unsigned int>
1325DisplacedProblem::determineSolverSystem(const std::string & var_name,
1326 const bool error_if_not_found) const
1327{
1328 return _mproblem.determineSolverSystem(var_name, error_if_not_found);
1329}
1330
1331Assembly &
1332DisplacedProblem::assembly(const THREAD_ID tid, const unsigned int sys_num)
1333{
1334 mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
1335 mooseAssert(sys_num < _assembly[tid].size(),
1336 "System number larger than the assembly container size");
1337 return *_assembly[tid][sys_num];
1338}
1339
1340const Assembly &
1341DisplacedProblem::assembly(const THREAD_ID tid, const unsigned int sys_num) const
1342{
1343 mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
1344 mooseAssert(sys_num < _assembly[tid].size(),
1345 "System number larger than the assembly container size");
1346 return *_assembly[tid][sys_num];
1347}
1348
1349std::size_t
1354
1355std::size_t
1360
1361std::size_t
1366
1367const std::vector<VectorTag> &
1372
1373bool
1378
1379bool
1384
1385void
1390
1391bool
1393{
1394 return _mproblem.haveFV();
1395}
1396
1397bool
1402
1403unsigned int
1404DisplacedProblem::nlSysNum(const NonlinearSystemName & nl_sys_name) const
1405{
1406 return _mproblem.nlSysNum(nl_sys_name);
1407}
1408
1409unsigned int
1410DisplacedProblem::linearSysNum(const LinearSystemName & sys_name) const
1411{
1412 return _mproblem.linearSysNum(sys_name);
1413}
1414
1415unsigned int
1416DisplacedProblem::solverSysNum(const SolverSystemName & sys_name) const
1417{
1418 return _mproblem.solverSysNum(sys_name);
1419}
1420
1423{
1425}
1426
1427bool
1432
1435 : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(fe_problem),
1436 _displaced_problem(displaced_problem),
1437 _ref_mesh(_displaced_problem.refMesh()),
1438 _nl_soln(_displaced_problem._nl_solution),
1439 _aux_soln(*_displaced_problem._aux_solution),
1440 _has_displacement(false)
1441{
1442 this->init();
1443}
1444
1447 : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(x, split),
1448 _displaced_problem(x._displaced_problem),
1450 _nl_soln(x._nl_soln),
1451 _aux_soln(x._aux_soln),
1452 _sys_to_nonghost_and_ghost_soln(x._sys_to_nonghost_and_ghost_soln),
1453 _sys_to_var_num_and_direction(x._sys_to_var_num_and_direction),
1454 _has_displacement(x._has_displacement)
1455{
1456}
1457
1458void
1460{
1461 std::vector<std::string> & displacement_variables = _displaced_problem._displacements;
1462 unsigned int num_displacements = displacement_variables.size();
1463 auto & es = _displaced_problem.es();
1464
1465 _sys_to_var_num_and_direction.clear();
1466 _sys_to_nonghost_and_ghost_soln.clear();
1467
1468 for (unsigned int i = 0; i < num_displacements; i++)
1469 {
1470 std::string displacement_name = displacement_variables[i];
1471
1472 for (const auto sys_num : make_range(es.n_systems()))
1473 {
1474 auto & sys = es.get_system(sys_num);
1475 if (sys.has_variable(displacement_name))
1476 {
1477 auto & val = _sys_to_var_num_and_direction[sys.number()];
1478 val.first.push_back(sys.variable_number(displacement_name));
1479 val.second.push_back(i);
1480 break;
1481 }
1482 }
1483 }
1484
1485 for (const auto & pr : _sys_to_var_num_and_direction)
1486 {
1487 auto & sys = es.get_system(pr.first);
1488 mooseAssert(sys.number() <= _nl_soln.size(),
1489 "The system number should always be less than or equal to the number of nonlinear "
1490 "systems. If it is equal, then this system is the auxiliary system");
1491 const NumericVector<Number> * const nonghost_soln =
1492 sys.number() < _nl_soln.size() ? _nl_soln[sys.number()] : &_aux_soln;
1493 _sys_to_nonghost_and_ghost_soln.emplace(
1494 sys.number(),
1495 std::make_pair(nonghost_soln,
1496 NumericVector<Number>::build(nonghost_soln->comm()).release()));
1497 }
1498
1499 ConstNodeRange node_range(_ref_mesh.getMesh().nodes_begin(), _ref_mesh.getMesh().nodes_end());
1500
1501 for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
1502 {
1503 auto & sys = es.get_system(sys_num);
1504 AllNodesSendListThread send_list(
1505 this->_fe_problem, _ref_mesh, var_num_and_direction.first, sys);
1506 Threads::parallel_reduce(node_range, send_list);
1507 send_list.unique();
1508 auto & [soln, ghost_soln] = libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num);
1509 ghost_soln->init(
1510 soln->size(), soln->local_size(), send_list.send_list(), true, libMesh::GHOSTED);
1511 soln->localize(*ghost_soln, send_list.send_list());
1512 }
1513
1514 _has_displacement = false;
1515}
1516
1517void
1519{
1520 Node & displaced_node = *(*nd);
1521
1522 Node & reference_node = _ref_mesh.nodeRef(displaced_node.id());
1523
1524 for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
1525 {
1526 auto & var_numbers = var_num_and_direction.first;
1527 auto & directions = var_num_and_direction.second;
1528 for (const auto i : index_range(var_numbers))
1529 {
1530 const auto direction = directions[i];
1531 if (reference_node.n_dofs(sys_num, var_numbers[i]) > 0)
1532 {
1533 Real coord = reference_node(direction) +
1534 (*libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num).second)(
1535 reference_node.dof_number(sys_num, var_numbers[i], 0));
1536 if (displaced_node(direction) != coord)
1537 {
1538 displaced_node(direction) = coord;
1539 _has_displacement = true;
1540 }
1541 }
1542 }
1543 }
1544}
boundary_id_type BoundaryID
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
const std::vector< dof_id_type > & send_list() const
Key structure for APIs manipulating global vectors/matrices.
Definition Assembly.h:845
Keeps track of stuff related to assembling.
Definition Assembly.h:110
void setCurrentNeighborSubdomainID(SubdomainID i)
set the current subdomain ID
Definition Assembly.h:502
void setCurrentSubdomainID(SubdomainID i)
set the current subdomain ID
Definition Assembly.h:424
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 reinitNodesNeighbor(const std::vector< dof_id_type > &nodes, const THREAD_ID tid) override
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.
virtual void reinitNodes(const std::vector< dof_id_type > &nodes, 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 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:4193
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:1690
void meshChanged()
Declares that the MooseMesh has changed, invalidates cached data and rebuilds caches.
Definition MooseMesh.C:889
virtual const Node & nodeRef(const dof_id_type i) const
Definition MooseMesh.C:841
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
void setCoordData(const MooseMesh &other_mesh)
Set the coordinate system data to that of other_mesh.
Definition MooseMesh.C:4443
void clearQuadratureNodes()
Clear out any existing quadrature nodes.
Definition MooseMesh.C:1667
virtual Elem * queryElemPtr(const dof_id_type i)
Definition MooseMesh.C:3226
const std::set< SubdomainID > & interiorLowerDBlocks() const
Definition MooseMesh.h:1552
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:222
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition SubProblem.C:204
virtual Moose::VectorTagType vectorTagType(const TagID tag_id) const
Definition SubProblem.C:232
virtual const VectorTag & getVectorTag(const TagID tag_id) const
Get a VectorTag from a TagID.
Definition SubProblem.C:162
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:173
virtual unsigned int numMatrixTags() const
The total number of tags.
Definition SubProblem.h:248
static InputParameters validParams()
Definition SubProblem.C:36
virtual TagID getMatrixTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition SubProblem.C:343
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:196
virtual TagName matrixTagName(TagID tag)
Retrieve the name associated with a TagID.
Definition SubProblem.C:358
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:93
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:329
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:312
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:958
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
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
dof_id_type id() const
unsigned int which_neighbor_am_i(const Elem *e) const
virtual unsigned short dim() const=0
subdomain_id_type subdomain_id() const
const Elem * neighbor_ptr(unsigned int i) const
unsigned int n_systems() const
const T_sys & get_system(std::string_view name) const
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
virtual bool is_serial() const
virtual bool contract()=0
virtual void allgather()
void clear_point_locator()
virtual void gather_to_zero()
virtual bool is_serial_on_zero() const
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
virtual numeric_index_type size() const=0
const Parallel::Communicator & comm() const
vec_type::const_iterator const_iterator
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())
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
auto index_range(const T &sizable)
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition MooseTypes.h:147
uint8_t dof_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
unsigned int n_threads()