https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SystemBase.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "MooseApp.h"
11#include "SystemBase.h"
12#include "Factory.h"
13#include "SubProblem.h"
14#include "MooseVariableFE.h"
15#include "MooseVariableFV.h"
16#include "MooseVariableScalar.h"
18#include "Conversion.h"
19#include "Parser.h"
21#include "MooseTypes.h"
22#include "InitialCondition.h"
24#include "Assembly.h"
25#include "MooseMesh.h"
26#include "MooseUtils.h"
27#include "FVBoundaryCondition.h"
28#include "FEProblemBase.h"
29#include "TimeIntegrator.h"
30#include "GradientLimiterType.h"
31#include "libmesh/dof_map.h"
32#include "libmesh/string_to_enum.h"
33#include "libmesh/fe_interface.h"
34#include "libmesh/static_condensation.h"
35
37void
38extraSendList(std::vector<dof_id_type> & send_list, void * context)
39{
40 SystemBase * sys = static_cast<SystemBase *>(context);
41 sys->augmentSendList(send_list);
42}
43
45void
47 std::vector<dof_id_type> & n_nz,
48 std::vector<dof_id_type> & n_oz,
49 void * context)
50{
51 SystemBase * sys = static_cast<SystemBase *>(context);
52 sys->augmentSparsity(sparsity, n_nz, n_oz);
53}
54
56 FEProblemBase & fe_problem,
57 const std::string & name,
58 Moose::VarKindType var_kind)
59 : libMesh::ParallelObject(subproblem),
60 ConsoleStreamInterface(subproblem.getMooseApp()),
61 _subproblem(subproblem),
62 _fe_problem(fe_problem),
63 _app(subproblem.getMooseApp()),
64 _factory(_app.getFactory()),
65 _mesh(subproblem.mesh()),
66 _name(name),
67 _vars(_app.numThreads()),
68 _var_map(),
69 _max_var_number(0),
70 _u_dot(nullptr),
71 _u_dotdot(nullptr),
72 _u_dot_old(nullptr),
73 _u_dotdot_old(nullptr),
74 _saved_old(nullptr),
75 _saved_older(nullptr),
76 _saved_dot_old(nullptr),
77 _saved_dotdot_old(nullptr),
78 _var_kind(var_kind),
79 _max_var_n_dofs_per_elem(0),
80 _max_var_n_dofs_per_node(0),
81 _automatic_scaling(false),
82 _verbose(false),
83 _solution_states_initialized(false),
84 _skip_next_solution_to_old_copy(false)
85{
86}
87
90
92SystemBase::getVariable(THREAD_ID tid, const std::string & var_name) const
93{
95 dynamic_cast<MooseVariableFieldBase *>(_vars[tid].getVariable(var_name));
96 if (!var)
97 mooseError("Variable '", var_name, "' does not exist in this system");
98 return *var;
99}
100
102SystemBase::getVariable(THREAD_ID tid, unsigned int var_number) const
103{
104 if (var_number < _numbered_vars[tid].size())
105 if (_numbered_vars[tid][var_number])
106 return *_numbered_vars[tid][var_number];
107
108 mooseError("Variable #", Moose::stringify(var_number), " does not exist in this system");
109}
110
111template <typename T>
113SystemBase::getFieldVariable(THREAD_ID tid, const std::string & var_name)
114{
115 return *_vars[tid].getFieldVariable<T>(var_name);
116}
117
118template <typename T>
120SystemBase::getActualFieldVariable(THREAD_ID tid, const std::string & var_name)
121{
122 return *_vars[tid].getActualFieldVariable<T>(var_name);
123}
124
125template <typename T>
127SystemBase::getFVVariable(THREAD_ID tid, const std::string & var_name)
128{
129 return *_vars[tid].getFVVariable<T>(var_name);
130}
131
132template <typename T>
134SystemBase::getFieldVariable(THREAD_ID tid, unsigned int var_number)
135{
136 return *_vars[tid].getFieldVariable<T>(var_number);
137}
138
139template <typename T>
142{
143 return *_vars[tid].getActualFieldVariable<T>(var_number);
144}
145
147SystemBase::getScalarVariable(THREAD_ID tid, const std::string & var_name) const
148{
149 MooseVariableScalar * var = dynamic_cast<MooseVariableScalar *>(_vars[tid].getVariable(var_name));
150 if (!var)
151 mooseError("Scalar variable '" + var_name + "' does not exist in this system");
152 return *var;
153}
154
156SystemBase::getScalarVariable(THREAD_ID tid, unsigned int var_number) const
157{
158 MooseVariableScalar * var =
159 dynamic_cast<MooseVariableScalar *>(_vars[tid].getVariable(var_number));
160 if (!var)
161 mooseError("variable #" + Moose::stringify(var_number) + " does not exist in this system");
162 return *var;
163}
164
165const std::set<SubdomainID> *
166SystemBase::getVariableBlocks(unsigned int var_number)
167{
168 mooseAssert(_var_map.find(var_number) != _var_map.end(), "Variable does not exist.");
169 if (_var_map[var_number].empty())
170 return nullptr;
171 else
172 return &_var_map[var_number];
173}
174
175void
177{
178 _vars_to_be_zeroed_on_residual.push_back(var_name);
179}
180
181void
183{
184 _vars_to_be_zeroed_on_jacobian.push_back(var_name);
185}
186
187void
188SystemBase::setVariableGlobalDoFs(const std::string & var_name)
189{
190 AllLocalDofIndicesThread aldit(_subproblem, {var_name});
191 const ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
192 Threads::parallel_reduce(elem_range, aldit, numThreads());
193
194 // Gather the dof indices across procs to get all the dof indices for var_name
195 aldit.dofIndicesSetUnion();
196
197 const auto & all_dof_indices = aldit.getDofIndices();
198 _var_all_dof_indices.assign(all_dof_indices.begin(), all_dof_indices.end());
199}
200
201void
202SystemBase::zeroVariables(std::vector<std::string> & vars_to_be_zeroed)
203{
204 if (vars_to_be_zeroed.size() > 0)
205 {
206 NumericVector<Number> & solution = this->solution();
207
208 auto problem = dynamic_cast<FEProblemBase *>(&_subproblem);
209 if (!problem)
210 mooseError("System needs to be registered in FEProblemBase for using zeroVariables.");
211
212 AllLocalDofIndicesThread aldit(*problem, vars_to_be_zeroed, true);
213 const ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
214 Threads::parallel_reduce(elem_range, aldit, numThreads());
215
216 const auto & dof_indices_to_zero = aldit.getDofIndices();
217
218 solution.close();
219
220 for (const auto & dof : dof_indices_to_zero)
221 solution.set(dof, 0);
222
223 solution.close();
224
225 // Call update to update the current_local_solution for this system
226 system().update();
227 }
228}
229
230void
235
236void
241
242Order
244{
245 Order order = CONSTANT;
246 const std::vector<MooseVariableFieldBase *> & vars = _vars[0].fieldVariables();
247 for (const auto & var : vars)
248 {
249 FEType fe_type = var->feType();
250 if (fe_type.default_quadrature_order() > order)
251 order = fe_type.default_quadrature_order();
252 }
253
254 return order;
255}
256
257void
259{
261 {
262 const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
264 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
265 for (const auto & var : vars)
266 var->clearDofIndices();
267
268 for (const auto & var : active_elemental_moose_variables)
269 if (&(var->sys()) == this)
270 var->prepare();
271 }
272 else
273 {
274 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
275 for (const auto & var : vars)
276 var->prepare();
277 }
278}
279
280void
281SystemBase::prepareFace(THREAD_ID tid, bool resize_data)
282{
283 // We only need to do something if the element prepare was restricted
285 {
286 const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
288
289 std::vector<MooseVariableFieldBase *> newly_prepared_vars;
290
291 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
292 for (const auto & var : vars)
293 {
294 mooseAssert(&var->sys() == this,
295 "I will cry if we store variables in our warehouse that don't belong to us");
296
297 // If it wasn't in the active list, we need to prepare it. This has the potential to duplicate
298 // prepare if we have these conditions:
299 //
300 // 1. We have a displaced problem
301 // 2. We are using AD
302 // 3. We are not using global AD indexing
303 //
304 // But I think I would rather risk duplicate prepare than introduce an additional member set
305 // variable for tracking prepared variables. Set insertion is slow and some simulations have a
306 // ton of variables
307 if (!active_elemental_moose_variables.count(var))
308 {
309 var->prepare();
310 newly_prepared_vars.push_back(var);
311 }
312 }
313
314 // Make sure to resize the residual and jacobian datastructures for all the new variables
315 if (resize_data)
316 for (const auto var_ptr : newly_prepared_vars)
317 {
318 _subproblem.assembly(tid, number()).prepareVariable(var_ptr);
320 _subproblem.assembly(tid, number()).prepareVariableNonlocal(var_ptr);
321 }
322 }
323}
324
325void
327{
328 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
329 for (const auto & var : vars)
330 var->prepareNeighbor();
331}
332
333void
335{
336 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
337 for (const auto & var : vars)
338 var->prepareLowerD();
339}
340
341void
342SystemBase::reinitElem(const Elem * const elem, THREAD_ID tid)
343{
345 {
346 const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
348 for (const auto & var : active_elemental_moose_variables)
349 if (&(var->sys()) == this)
350 var->computeElemValues();
351 }
352 else
353 {
354 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
355 for (const auto & var : vars)
356 var->computeElemValues();
357 }
358
360 for (auto & [tag, matrix] : _active_tagged_matrices)
361 {
362 libmesh_ignore(tag);
363 cast_ptr<libMesh::StaticCondensation *>(matrix)->set_current_elem(*elem);
364 }
365}
366
367void
368SystemBase::reinitElemFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
369{
370 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
371 for (const auto & var : vars)
372 var->computeElemValuesFace();
373}
374
375void
376SystemBase::reinitNeighborFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
377{
378 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
379 for (const auto & var : vars)
380 var->computeNeighborValuesFace();
381}
382
383void
384SystemBase::reinitNeighbor(const Elem * /*elem*/, THREAD_ID tid)
385{
386 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
387 for (const auto & var : vars)
388 var->computeNeighborValues();
389}
390
391void
393{
394 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
395 for (const auto & var : vars)
396 var->computeLowerDValues();
397}
398
399void
400SystemBase::reinitNode(const Node * /*node*/, THREAD_ID tid)
401{
402 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
403 for (const auto & var : vars)
404 {
405 var->reinitNode();
406 if (var->isNodalDefined())
407 var->computeNodalValues();
408 }
409}
410
411void
412SystemBase::reinitNodeFace(const Node * /*node*/, BoundaryID /*bnd_id*/, THREAD_ID tid)
413{
414 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
415 for (const auto & var : vars)
416 {
417 var->reinitNode();
418 if (var->isNodalDefined())
419 var->computeNodalValues();
420 }
421}
422
423void
424SystemBase::reinitNodes(const std::vector<dof_id_type> & nodes, THREAD_ID tid)
425{
426 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
427 for (const auto & var : vars)
428 {
429 var->reinitNodes(nodes);
430 var->computeNodalValues();
431 }
432}
433
434void
435SystemBase::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes, THREAD_ID tid)
436{
437 const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
438 for (const auto & var : vars)
439 {
440 var->reinitNodesNeighbor(nodes);
441 var->computeNodalNeighborValues();
442 }
443}
444
445void
446SystemBase::reinitScalars(THREAD_ID tid, bool reinit_for_derivative_reordering /*=false*/)
447{
448 const std::vector<MooseVariableScalar *> & vars = _vars[tid].scalars();
449 for (const auto & var : vars)
450 var->reinit(reinit_for_derivative_reordering);
451}
452
453void
454SystemBase::augmentSendList(std::vector<dof_id_type> & send_list)
455{
456 std::set<dof_id_type> & ghosted_elems = _subproblem.ghostedElems();
457
458 DofMap & dof_map = dofMap();
459
460 std::vector<dof_id_type> dof_indices;
461
462 System & sys = system();
463
464 unsigned int sys_num = sys.number();
465
466 unsigned int n_vars = sys.n_vars();
467
468 for (const auto & elem_id : ghosted_elems)
469 {
470 Elem * elem = _mesh.elemPtr(elem_id);
471
472 if (elem->active())
473 {
474 dof_map.dof_indices(elem, dof_indices);
475
476 // Only need to ghost it if it's actually not on this processor
477 for (const auto & dof : dof_indices)
478 if (dof < dof_map.first_dof() || dof >= dof_map.end_dof())
479 send_list.push_back(dof);
480
481 // Now add the DoFs from all of the nodes. This is necessary because of block
482 // restricted variables. A variable might not live _on_ this element but it
483 // might live on nodes connected to this element.
484 for (unsigned int n = 0; n < elem->n_nodes(); n++)
485 {
486 Node * node = elem->node_ptr(n);
487
488 // Have to get each variable's dofs
489 for (unsigned int v = 0; v < n_vars; v++)
490 {
491 const libMesh::Variable & var = sys.variable(v);
492 unsigned int var_num = var.number();
493 unsigned int n_comp = var.n_components();
494
495 // See if this variable has any dofs at this node
496 if (node->n_dofs(sys_num, var_num) > 0)
497 {
498 // Loop over components of the variable
499 for (unsigned int c = 0; c < n_comp; c++)
500 send_list.push_back(node->dof_number(sys_num, var_num, c));
501 }
502 }
503 }
504 }
505 }
506}
507
511void
513{
515 if (num_states > 1)
516 {
517 _saved_solution_states.resize(num_states);
518 for (unsigned int i = 1; i <= num_states - 1; ++i)
521 &addVector("save_solution_state_" + std::to_string(i), false, PARALLEL);
522
523 for (unsigned int i = 1; i <= num_states - 1; ++i)
525 }
526
528 _saved_dot_old = &addVector("save_solution_dot_old", false, PARALLEL);
530 _saved_dotdot_old = &addVector("save_solution_dotdot_old", false, PARALLEL);
531
532 if (solutionUDotOld())
534
535 if (solutionUDotDotOld())
537}
538
542void
544{
546 if (num_states > 1)
547 for (unsigned int i = 1; i <= num_states - 1; ++i)
549 {
551 removeVector("save_solution_state_" + std::to_string(i));
552 _saved_solution_states[i] = nullptr;
553 }
554
556 {
558 removeVector("save_solution_dot_old");
559 _saved_dot_old = nullptr;
560 }
562 {
564 removeVector("save_solution_dotdot_old");
565 _saved_dotdot_old = nullptr;
566 }
567}
568
569SparseMatrix<Number> &
571{
573 mooseError("Cannot add tagged matrix with TagID ",
574 tag,
575 " in system '",
576 name(),
577 "' because the tag does not exist in the problem");
578
579 if (hasMatrix(tag))
580 return getMatrix(tag);
581
582 const auto matrix_name = _subproblem.matrixTagName(tag);
583 SparseMatrix<Number> & mat = system().add_matrix(matrix_name);
584 associateMatrixToTag(mat, tag);
585
586 return mat;
587}
588
589void
591{
592 if (!_subproblem.matrixTagExists(tag_id))
593 mooseError("Cannot remove the matrix with TagID ",
594 tag_id,
595 "\nin system '",
596 name(),
597 "', because that tag does not exist in the problem");
598
599 if (hasMatrix(tag_id))
600 {
601 const auto matrix_name = _subproblem.matrixTagName(tag_id);
602 system().remove_matrix(matrix_name);
603 _tagged_matrices[tag_id] = nullptr;
604 }
605}
606
607NumericVector<Number> &
608SystemBase::addVector(const std::string & vector_name,
609 const bool project,
610 const libMesh::ParallelType type)
611{
612 if (hasVector(vector_name))
613 return getVector(vector_name);
614
615 NumericVector<Number> & vec = system().add_vector(vector_name, project, type);
616 return vec;
617}
618
619NumericVector<Number> &
620SystemBase::addVector(TagID tag, const bool project, const libMesh::ParallelType type)
621{
623 mooseError("Cannot add tagged vector with TagID ",
624 tag,
625 " in system '",
626 name(),
627 "' because the tag does not exist in the problem");
628
629 if (hasVector(tag))
630 {
631 auto & vec = getVector(tag);
632
633 if (type != AUTOMATIC && vec.type() != type)
634 mooseError("Cannot add tagged vector '",
636 "', in system '",
637 name(),
638 "' because a vector with the same name was found with a different parallel type");
639
640 return vec;
641 }
642
643 const auto vector_name = _subproblem.vectorTagName(tag);
644 NumericVector<Number> & vec = system().add_vector(vector_name, project, type);
645 associateVectorToTag(vec, tag);
646
647 return vec;
648}
649
650void
652{
654 mooseError("Cannot close vector with TagID ",
655 tag,
656 " in system '",
657 name(),
658 "' because that tag does not exist in the problem");
659 else if (!hasVector(tag))
660 mooseError("Cannot close vector tag with name '",
662 "' in system '",
663 name(),
664 "' because there is no vector associated with that tag");
665 getVector(tag).close();
666}
667
668void
669SystemBase::closeTaggedVectors(const std::set<TagID> & tags)
670{
671 for (const auto tag : tags)
673}
674
675void
677{
679 mooseError("Cannot zero vector with TagID ",
680 tag,
681 " in system '",
682 name(),
683 "' because that tag does not exist in the problem");
684 else if (!hasVector(tag))
685 mooseError("Cannot zero vector tag with name '",
687 "' in system '",
688 name(),
689 "' because there is no vector associated with that tag");
691 getVector(tag).zero();
692}
693
694void
695SystemBase::zeroTaggedVectors(const std::set<TagID> & tags)
696{
697 for (const auto tag : tags)
698 zeroTaggedVector(tag);
699}
700
701void
703{
704 if (!_subproblem.vectorTagExists(tag_id))
705 mooseError("Cannot remove the vector with TagID ",
706 tag_id,
707 "\nin system '",
708 name(),
709 "', because that tag does not exist in the problem");
710
711 if (hasVector(tag_id))
712 {
713 auto vector_name = _subproblem.vectorTagName(tag_id);
714 system().remove_vector(vector_name);
715 _tagged_vectors[tag_id] = nullptr;
716 }
717}
718
719void
720SystemBase::addVariable(const std::string & var_type,
721 const std::string & name,
722 InputParameters & parameters)
723{
724 _numbered_vars.resize(numThreads());
725
726 const auto components = parameters.get<unsigned int>("components");
727
728 // Convert the std::vector parameter provided by the user into a std::set for use by libMesh's
729 // System::add_variable method
730 std::set<SubdomainID> blocks;
731 const auto & block_param = parameters.get<std::vector<SubdomainName>>("block");
732 for (const auto & subdomain_name : block_param)
733 {
734 SubdomainID blk_id = _mesh.getSubdomainID(subdomain_name);
735 blocks.insert(blk_id);
736 }
737
738 const auto fe_type = MooseUtils::variableFEType(parameters);
739 const auto fe_field_type = FEInterface::field_type(fe_type);
740
741 unsigned int var_num;
742
743 if (var_type == "ArrayMooseVariable")
744 {
745 if (fe_field_type == libMesh::TYPE_VECTOR)
746 mooseError("Vector family type cannot be used in an array variable");
747
748 std::vector<std::string> array_var_component_names;
749 const bool has_array_names = parameters.isParamValid("array_var_component_names");
750 if (has_array_names)
751 {
752 array_var_component_names =
753 parameters.get<std::vector<std::string>>("array_var_component_names");
754 if (array_var_component_names.size() != components)
755 parameters.paramError("array_var_component_names",
756 "Must be the same size as 'components' (size ",
757 components,
758 ") for array variable '",
759 name,
760 "'");
761 }
762
763 // Build up the variable names
764 std::vector<std::string> var_names;
765 for (unsigned int i = 0; i < components; i++)
766 {
767 if (!has_array_names)
768 array_var_component_names.push_back(std::to_string(i));
769 var_names.push_back(name + "_" + array_var_component_names[i]);
770 }
771
772 // makes sure there is always a name, either the provided one or '1 2 3 ...'
773 parameters.set<std::vector<std::string>>("array_var_component_names") =
774 array_var_component_names;
775
776 // The number returned by libMesh is the _last_ variable number... we want to hold onto the
777 // _first_
778 var_num = system().add_variable_array(var_names, fe_type, &blocks) - (components - 1);
779
780 // Set as array variable
781 if (parameters.isParamSetByUser("array") && !parameters.get<bool>("array"))
782 parameters.paramError("array",
783 "Must be set to true for variable '",
784 name,
785 "' because 'components' > 1 (is an array variable)");
786 parameters.set<bool>("array") = true;
787 }
788 else
789 {
790 if (parameters.isParamSetByUser("array_var_component_names"))
791 parameters.paramError("array_var_component_names",
792 "Should not be set because this variable (",
793 name,
794 ") is a non-array variable");
795 var_num = system().add_variable(name, fe_type, &blocks);
796 }
797
798 parameters.set<unsigned int>("_var_num") = var_num;
799 parameters.set<SystemBase *>("_system_base") = this;
800
801 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
802 {
803 parameters.set<THREAD_ID>("tid") = tid;
804 std::shared_ptr<MooseVariableBase> var =
805 _factory.create<MooseVariableBase>(var_type, name, parameters, tid);
806
807 _vars[tid].add(name, var);
808
809 if (auto fe_var = dynamic_cast<MooseVariableFieldBase *>(var.get()))
810 {
811 auto required_size = var_num + components;
812 if (required_size > _numbered_vars[tid].size())
813 _numbered_vars[tid].resize(required_size);
814 for (MooseIndex(components) component = 0; component < components; ++component)
815 _numbered_vars[tid][var_num + component] = fe_var;
816
817 if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADReal> *>(fe_var))
818 _subproblem.addFunctor(name, *functor, tid);
819 else if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADRealVectorValue> *>(fe_var))
820 _subproblem.addFunctor(name, *functor, tid);
821 else if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADRealEigenVector> *>(fe_var))
822 _subproblem.addFunctor(name, *functor, tid);
823 else
824 mooseError("This should be a functor");
825 }
826
827 if (auto scalar_var = dynamic_cast<MooseVariableScalar *>(var.get()))
828 {
829 if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADReal> *>(scalar_var))
830 _subproblem.addFunctor(name, *functor, tid);
831 else
832 mooseError("Scalar variables should be functors");
833 }
834
835 if (var->blockRestricted())
836 for (const SubdomainID & id : var->blockIDs())
837 for (MooseIndex(components) component = 0; component < components; ++component)
838 _var_map[var_num + component].insert(id);
839 else
840 for (MooseIndex(components) component = 0; component < components; ++component)
841 _var_map[var_num + component] = std::set<SubdomainID>();
842 }
843
844 // getMaxVariableNumber is an API method used in Rattlesnake
845 if (var_num > _max_var_number)
846 _max_var_number = var_num;
847 _du_dot_du.resize(var_num + 1);
848}
849
850bool
851SystemBase::hasVariable(const std::string & var_name) const
852{
853 auto & names = getVariableNames();
854 if (system().has_variable(var_name))
855 return system().variable_type(var_name).family != SCALAR;
856 if (std::find(names.begin(), names.end(), var_name) != names.end())
857 // array variable
858 return true;
859 else
860 return false;
861}
862
863bool
864SystemBase::isArrayVariable(const std::string & var_name) const
865{
866 auto & names = getVariableNames();
867 if (!system().has_variable(var_name) &&
868 std::find(names.begin(), names.end(), var_name) != names.end())
869 // array variable
870 return true;
871 else
872 return false;
873}
874
875bool
876SystemBase::hasScalarVariable(const std::string & var_name) const
877{
878 if (system().has_variable(var_name))
879 return system().variable_type(var_name).family == SCALAR;
880 else
881 return false;
882}
883
884bool
885SystemBase::isScalarVariable(unsigned int var_num) const
886{
887 return (system().variable(var_num).type().family == SCALAR);
888}
889
890unsigned int
892{
893 unsigned int n = nFieldVariables();
894 n += _vars[0].scalars().size();
895
896 return n;
897}
898
899unsigned int
901{
902 unsigned int n = 0;
903 for (auto & var : _vars[0].fieldVariables())
904 n += var->count();
905
906 return n;
907}
908
909unsigned int
911{
912 unsigned int n = 0;
913 for (auto & var : _vars[0].fieldVariables())
914 if (var->isFV())
915 n += var->count();
916
917 return n;
918}
919
923bool
924SystemBase::hasVector(const std::string & name) const
925{
926 return system().have_vector(name);
927}
928
932NumericVector<Number> &
933SystemBase::getVector(const std::string & name)
934{
936}
937
938const NumericVector<Number> &
939SystemBase::getVector(const std::string & name) const
940{
941 return system().get_vector(name);
942}
943
944NumericVector<Number> &
946{
947 if (!hasVector(tag))
948 {
950 mooseError("Cannot retrieve vector with tag ", tag, " because that tag does not exist");
951 else
952 mooseError("Cannot retrieve vector with tag ",
953 tag,
954 " in system '",
955 name(),
956 "'\nbecause a vector has not been associated with that tag.");
957 }
958
959 return *_tagged_vectors[tag];
960}
961
962const NumericVector<Number> &
964{
965 if (!hasVector(tag))
966 {
968 mooseError("Cannot retrieve vector with tag ", tag, " because that tag does not exist");
969 else
970 mooseError("Cannot retrieve vector with tag ",
971 tag,
972 " in system '",
973 name(),
974 "'\nbecause a vector has not been associated with that tag.");
975 }
976
977 return *_tagged_vectors[tag];
978}
979
980void
981SystemBase::associateVectorToTag(NumericVector<Number> & vec, TagID tag)
982{
984 mooseError("Cannot associate vector to tag ", tag, " because that tag does not exist");
985
986 if (_tagged_vectors.size() < tag + 1)
987 _tagged_vectors.resize(tag + 1);
988
989 _tagged_vectors[tag] = &vec;
990}
991
992void
993SystemBase::disassociateVectorFromTag(NumericVector<Number> & vec, TagID tag)
994{
996 mooseError("Cannot disassociate vector from tag ", tag, " because that tag does not exist");
997 if (hasVector(tag) && &getVector(tag) != &vec)
998 mooseError("You can not disassociate a vector from a tag which it was not associated to");
999
1001}
1002
1003void
1005{
1006 if (!_subproblem.vectorTagExists(tag))
1007 mooseError("Cannot disassociate vector from tag ", tag, " because that tag does not exist");
1008
1009 if (_tagged_vectors.size() < tag + 1)
1010 _tagged_vectors.resize(tag + 1);
1011 _tagged_vectors[tag] = nullptr;
1012}
1013
1014void
1016{
1017 const auto tags = defaultVectorTags();
1018 for (const auto tag : tags)
1021}
1022
1023SparseMatrix<Number> &
1025{
1026 if (!hasMatrix(tag))
1027 {
1028 if (!_subproblem.matrixTagExists(tag))
1029 mooseError("Cannot retrieve matrix with tag ", tag, " because that tag does not exist");
1030 else
1031 mooseError("Cannot retrieve matrix with tag ",
1032 tag,
1033 " in system '",
1034 name(),
1035 "'\nbecause a matrix has not been associated with that tag.");
1036 }
1037
1038 return *_tagged_matrices[tag];
1039}
1040
1041const SparseMatrix<Number> &
1043{
1044 if (!hasMatrix(tag))
1045 {
1046 if (!_subproblem.matrixTagExists(tag))
1047 mooseError("Cannot retrieve matrix with tag ", tag, " because that tag does not exist");
1048 else
1049 mooseError("Cannot retrieve matrix with tag ",
1050 tag,
1051 " in system '",
1052 name(),
1053 "'\nbecause a matrix has not been associated with that tag.");
1054 }
1055
1056 return *_tagged_matrices[tag];
1057}
1058
1059void
1060SystemBase::closeTaggedMatrices(const std::set<TagID> & tags)
1061{
1062 for (auto tag : tags)
1063 if (hasMatrix(tag))
1064 getMatrix(tag).close();
1065}
1066
1067void
1068SystemBase::flushTaggedMatrices(const std::set<TagID> & tags)
1069{
1070 for (auto tag : tags)
1071 if (hasMatrix(tag))
1072 getMatrix(tag).flush();
1073}
1074
1075void
1076SystemBase::associateMatrixToTag(SparseMatrix<Number> & matrix, TagID tag)
1077{
1078 if (!_subproblem.matrixTagExists(tag))
1079 mooseError("Cannot associate matrix to tag ", tag, " because that tag does not exist");
1080
1081 if (_tagged_matrices.size() < tag + 1)
1082 _tagged_matrices.resize(tag + 1);
1083
1084 _tagged_matrices[tag] = &matrix;
1085}
1086
1087void
1088SystemBase::disassociateMatrixFromTag(SparseMatrix<Number> & matrix, TagID tag)
1089{
1090 if (!_subproblem.matrixTagExists(tag))
1091 mooseError("Cannot disassociate matrix from tag ", tag, " because that tag does not exist");
1092 if (hasMatrix(tag) && &getMatrix(tag) != &matrix)
1093 mooseError("You can not disassociate a matrix from a tag which it was not associated to");
1094
1096}
1097
1098void
1100{
1101 if (!_subproblem.matrixTagExists(tag))
1102 mooseError("Cannot disassociate matrix from tag ", tag, " because that tag does not exist");
1103
1104 if (_tagged_matrices.size() < tag + 1)
1105 _tagged_matrices.resize(tag + 1);
1106 _tagged_matrices[tag] = nullptr;
1107}
1108
1109void
1111{
1112 const auto tags = defaultMatrixTags();
1113 for (const auto tag : tags)
1116}
1117
1118void
1120{
1121 auto num_matrix_tags = _subproblem.numMatrixTags();
1122
1123 _matrix_tag_active_flags.resize(num_matrix_tags);
1124
1125 for (decltype(num_matrix_tags) tag = 0; tag < num_matrix_tags; tag++)
1126 _matrix_tag_active_flags[tag] = false;
1128}
1129
1130void
1132{
1133 auto num_matrix_tags = _subproblem.numMatrixTags();
1134
1135 _matrix_tag_active_flags.resize(num_matrix_tags);
1137
1138 for (const auto tag : make_range(num_matrix_tags))
1139 if (hasMatrix(tag))
1140 {
1141 _matrix_tag_active_flags[tag] = true;
1142 _active_tagged_matrices.emplace(tag, &getMatrix(tag));
1143 }
1144 else
1145 _matrix_tag_active_flags[tag] = false;
1146}
1147
1148bool
1150{
1151 mooseAssert(_subproblem.matrixTagExists(tag), "Matrix tag " << tag << " does not exist");
1152
1153 return tag < _matrix_tag_active_flags.size() && _matrix_tag_active_flags[tag];
1154}
1155
1156unsigned int
1158{
1159 return system().number();
1160}
1161
1162DofMap &
1164{
1165 return system().get_dof_map();
1166}
1167
1168const DofMap &
1170{
1171 return system().get_dof_map();
1172}
1173
1174void
1175SystemBase::addVariableToCopy(const std::string & dest_name,
1176 const std::string & source_name,
1177 const std::string & timestep)
1178{
1179 _var_to_copy.push_back(VarCopyInfo(dest_name, source_name, timestep));
1180}
1181
1182void
1183SystemBase::copyVars(ExodusII_IO & io)
1184{
1185 int n_steps = io.get_num_time_steps();
1186
1187 bool did_copy = false;
1188 for (const auto & vci : _var_to_copy)
1189 {
1190 int timestep = -1;
1191
1192 if (vci._timestep == "LATEST")
1193 // Use the last time step in the file from which to retrieve the solution
1194 timestep = n_steps;
1195 else
1196 {
1197 timestep = MooseUtils::convert<int>(vci._timestep);
1198 if (timestep > n_steps)
1199 mooseError("Invalid value passed as \"initial_from_file_timestep\". Expected \"LATEST\" or "
1200 "a valid integer between 1 and ",
1201 n_steps,
1202 " inclusive, received ",
1203 vci._timestep);
1204 }
1205
1206 did_copy = true;
1207
1208 if (hasVariable(vci._dest_name))
1209 {
1210 const auto & var = getVariable(0, vci._dest_name);
1211 if (var.isArray())
1212 {
1213 const auto & array_var = getFieldVariable<RealEigenVector>(0, vci._dest_name);
1214 for (MooseIndex(var.count()) i = 0; i < var.count(); ++i)
1215 {
1216 const auto & exodus_var = var.arrayVariableComponent(i);
1217 const auto & system_var = array_var.componentName(i);
1218 if (var.isNodal())
1219 io.copy_nodal_solution(system(), exodus_var, system_var, timestep);
1220 else
1221 io.copy_elemental_solution(system(), exodus_var, system_var, timestep);
1222 }
1223 }
1224 else
1225 {
1226 if (var.isNodal())
1227 io.copy_nodal_solution(system(), vci._dest_name, vci._source_name, timestep);
1228 else
1229 io.copy_elemental_solution(system(), vci._dest_name, vci._source_name, timestep);
1230 }
1231 }
1232 else if (hasScalarVariable(vci._dest_name))
1233 io.copy_scalar_solution(system(), {vci._dest_name}, {vci._source_name}, timestep);
1234 else
1235 mooseError("Unrecognized variable ", vci._dest_name, " in variables to copy.");
1236 }
1237
1238 if (did_copy)
1239 solution().close();
1240}
1241
1242void
1244{
1245 system().update();
1246}
1247
1248void
1250{
1251 system().solve();
1252}
1253
1257void
1264
1265void
1272
1273void
1275{
1276 // Normally copy through old (index 1). For Time, optionally stop at older
1277 // and leave old unchanged.
1278 const bool skip_old =
1280
1281 const auto num_states = getNumSolutionStates(iteration_type);
1282 if (num_states > 1)
1283 {
1284 const std::size_t stop = skip_old ? 1 : 0;
1285 for (std::size_t i = num_states - 1; i > stop; --i)
1286 solutionState(i, iteration_type) = solutionState(i - 1, iteration_type);
1287 }
1288
1289 // Custom logic for changing state based on iteration type
1290 switch (iteration_type)
1291 {
1294 if (solutionUDotOld())
1296 if (solutionUDotDotOld())
1298 break;
1302 break;
1306 break;
1307 }
1308}
1309
1310void
1312{
1313 const bool skip_current_to_old =
1315 copyPreviousSolutions(iteration_type);
1316 copyAdditionalStateBackwards(iteration_type, skip_current_to_old);
1317}
1318
1322void
1327
1331void
1333{
1334 if (!hasSolutionState(1))
1335 mooseError("Cannot restore solutions without old solution");
1336
1337 *(const_cast<NumericVector<Number> *&>(currentSolution())) = solutionOld();
1338 solution() = solutionOld();
1339 if (solutionUDotOld())
1341 if (solutionUDotDotOld())
1345 system().update();
1346}
1347
1348void
1354
1355void
1356SystemBase::removeVector(const std::string & name)
1357{
1359}
1360
1361const std::string &
1363{
1364 return system().name();
1365}
1366
1367NumericVector<Number> *
1375
1376const NumericVector<Number> *
1378{
1381 else
1382 return nullptr;
1383}
1384
1385void
1387{
1388 // Default is the current solution
1389 unsigned int state = 0;
1390
1391 // Add additional states as required by the variable states requested
1392 for (const auto & var : getVariables(/* tid = */ 0))
1393 state = std::max(state, var->oldestSolutionStateRequested());
1394 for (const auto & var : getScalarVariables(/* tid = */ 0))
1395 state = std::max(state, var->oldestSolutionStateRequested());
1396
1398
1400}
1401
1402TagName
1404 const Moose::SolutionIterationType iteration_type) const
1405{
1406 mooseAssert(state != 0, "Not an old state");
1407 mooseAssert(static_cast<unsigned short>(iteration_type) <
1408 static_cast<unsigned short>(Moose::SolutionIterationType::Count),
1409 "Invalid iteration_type");
1410
1411 switch (iteration_type)
1412 {
1414 if (state == 1)
1416 else if (state == 2)
1418 break;
1420 if (state == 1)
1422 break;
1424 if (state == 1)
1426 break;
1428 if (state == 1)
1430 break;
1432 break;
1433 }
1434
1435 return "solution_state_" + std::to_string(state) + "_" + Moose::stringify(iteration_type);
1436}
1437
1438const NumericVector<Number> &
1439SystemBase::solutionState(const unsigned int state,
1440 const Moose::SolutionIterationType iteration_type) const
1441{
1442 if (!hasSolutionState(state, iteration_type))
1443 {
1444 const auto num_states = getNumSolutionStates(iteration_type);
1445 mooseError("For iteration type '",
1446 Moose::stringify(iteration_type),
1447 "': solution state ",
1448 state,
1449 " was requested in ",
1450 name(),
1451 " but only up to state ",
1452 (num_states == 0) ? 0 : num_states - 1,
1453 " is available.");
1454 }
1455
1456 const auto & solution_states = getSolutionStates(iteration_type);
1457
1458 if (state == 0)
1459 mooseAssert(solution_states[0] == &solutionInternal(), "Inconsistent current solution");
1460 else
1461 mooseAssert(solution_states[state] ==
1462 &getVector(oldSolutionStateVectorName(state, iteration_type)),
1463 "Inconsistent solution state");
1464
1465 return *solution_states[state];
1466}
1467
1468NumericVector<Number> &
1469SystemBase::solutionState(const unsigned int state,
1470 const Moose::SolutionIterationType iteration_type)
1471{
1472 if (!hasSolutionState(state, iteration_type))
1473 needSolutionState(state, iteration_type);
1474 return *getSolutionStates(iteration_type)[state];
1475}
1476
1479 const Moose::SolutionIterationType iteration_type) const
1480{
1481 if (!hasSolutionState(state, iteration_type))
1482 mooseError("solutionStateParallelType() may only be called if the solution state exists.");
1483 return getSolutionStates(iteration_type)[state]->type();
1484}
1485
1486void
1487SystemBase::needSolutionState(const unsigned int state,
1488 const Moose::SolutionIterationType iteration_type,
1489 const libMesh::ParallelType parallel_type)
1490{
1491 libmesh_parallel_only(this->comm());
1492 mooseAssert(!Threads::in_threads,
1493 "This routine is not thread-safe. Request the solution state before using it in "
1494 "a threaded region.");
1495
1496 if (hasSolutionState(state, iteration_type))
1497 return;
1498
1499 auto & solution_states = getSolutionStates(iteration_type);
1500 solution_states.resize(state + 1);
1501
1502 // The 0-th (current) solution state is owned by libMesh
1503 if (!solution_states[0])
1504 solution_states[0] = &solutionInternal();
1505 else
1506 mooseAssert(solution_states[0] == &solutionInternal(), "Inconsistent current solution");
1507
1508 // We will manually add all states past current
1509 for (unsigned int i = 1; i <= state; ++i)
1510 if (!solution_states[i])
1511 {
1512 auto tag = _subproblem.addVectorTag(oldSolutionStateVectorName(i, iteration_type),
1514 solution_states[i] = &addVector(tag, true, parallel_type);
1515 }
1516 else
1517 {
1518 // If the existing parallel type is PARALLEL and GHOSTED is now requested,
1519 // this would require an upgrade, which is risky if anybody has already
1520 // stored a pointer to the existing vector, since the upgrade would create
1521 // a new vector and make that pointer null. If the existing parallel type
1522 // is GHOSTED and PARALLEL is now requested, we don't need to do anything.
1523 if (parallel_type == GHOSTED && solutionStateParallelType(i, iteration_type) == PARALLEL)
1524 mooseError("The solution state has already been declared as PARALLEL");
1525
1526 mooseAssert(solution_states[i] == &getVector(oldSolutionStateVectorName(i, iteration_type)),
1527 "Inconsistent solution state");
1528 }
1529}
1530
1531void
1532SystemBase::applyScalingFactors(const std::vector<Real> & inverse_scaling_factors)
1533{
1534 for (MooseIndex(_vars) thread = 0; thread < _vars.size(); ++thread)
1535 {
1536 auto & field_variables = _vars[thread].fieldVariables();
1537 for (MooseIndex(field_variables) i = 0, p = 0; i < field_variables.size(); ++i)
1538 {
1539 auto factors = field_variables[i]->arrayScalingFactor();
1540 for (unsigned int j = 0; j < field_variables[i]->count(); ++j, ++p)
1541 factors[j] /= inverse_scaling_factors[p];
1542
1543 field_variables[i]->scalingFactor(factors);
1544 }
1545
1546 auto offset = field_variables.size();
1547
1548 auto & scalar_variables = _vars[thread].scalars();
1549 for (MooseIndex(scalar_variables) i = 0; i < scalar_variables.size(); ++i)
1550 scalar_variables[i]->scalingFactor(
1551 {1. / inverse_scaling_factors[offset + i] * scalar_variables[i]->scalingFactor()});
1552
1553 if (thread == 0 && _verbose)
1554 {
1555 _console << "Automatic scaling factors:\n";
1556 auto original_flags = _console.flags();
1557 auto original_precision = _console.precision();
1558 _console.unsetf(std::ios_base::floatfield);
1560
1561 for (const auto & field_variable : field_variables)
1562 {
1563 const auto & factors = field_variable->arrayScalingFactor();
1564 _console << " " << field_variable->name() << ":";
1565 for (const auto i : make_range(field_variable->count()))
1566 _console << " " << factors[i];
1567 _console << "\n";
1568 }
1569 for (const auto & scalar_variable : scalar_variables)
1570 _console << " " << scalar_variable->name() << ": " << scalar_variable->scalingFactor()
1571 << "\n";
1572 _console << "\n" << std::endl;
1573
1574 // restore state
1575 _console.flags(original_flags);
1576 _console.precision(original_precision);
1577 }
1578 }
1579}
1580
1581bool
1586
1587void
1589{
1590 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1591 _vars[tid].initialSetup();
1592}
1593
1594void
1596{
1597 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1598 _vars[tid].timestepSetup();
1599}
1600
1601void
1603{
1604 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1605 _vars[tid].customSetup(exec_type);
1606}
1607
1608void
1610{
1611 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1612 _vars[tid].subdomainSetup();
1613}
1614
1615void
1617{
1618 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1619 _vars[tid].residualSetup();
1620}
1621
1622void
1624{
1625 for (THREAD_ID tid = 0; tid < numThreads(); tid++)
1626 _vars[tid].jacobianSetup();
1627}
1628
1629void
1631{
1632 for (auto & var_warehouse : _vars)
1633 var_warehouse.clearAllDofIndices();
1634}
1635
1636void
1638{
1639 _vars[tid].setActiveVariableCoupleableVectorTags(vtags);
1640}
1641
1642void
1644 THREAD_ID tid)
1645{
1646 _vars[tid].setActiveScalarVariableCoupleableVectorTags(vtags);
1647}
1648
1649void
1651{
1653 _u_dot = &addVector("u_dot", true, GHOSTED);
1655 _u_dot_old = &addVector("u_dot_old", true, GHOSTED);
1657 _u_dotdot = &addVector("u_dotdot", true, GHOSTED);
1659 _u_dotdot_old = &addVector("u_dotdot_old", true, GHOSTED);
1660}
1661
1662NumericVector<Number> &
1664{
1665 if (!_serialized_solution.get())
1666 {
1667 _serialized_solution = NumericVector<Number>::build(_communicator);
1668 _serialized_solution->init(system().n_dofs(), false, SERIAL);
1669 }
1670
1671 return *_serialized_solution;
1672}
1673
1674void
1675SystemBase::addTimeIntegrator(const std::string & type,
1676 const std::string & name,
1677 InputParameters & parameters)
1678{
1679 parameters.set<SystemBase *>("_sys") = this;
1680 _time_integrators.push_back(_factory.create<TimeIntegrator>(type, name, parameters));
1681}
1682
1683void
1688
1689const TimeIntegrator *
1690SystemBase::queryTimeIntegrator(const unsigned int var_num) const
1691{
1692 for (auto & ti : _time_integrators)
1693 if (ti->integratesVar(var_num))
1694 return ti.get();
1695
1696 return nullptr;
1697}
1698
1699const TimeIntegrator &
1700SystemBase::getTimeIntegrator(const unsigned int var_num) const
1701{
1702 const auto * const ti = queryTimeIntegrator(var_num);
1703
1704 if (ti)
1705 return *ti;
1706 else
1707 mooseError("No time integrator found that integrates variable number ",
1708 std::to_string(var_num));
1709}
1710
1711const std::vector<std::shared_ptr<TimeIntegrator>> &
1716
1717const Number &
1718SystemBase::duDotDu(const unsigned int var_num) const
1719{
1720 return _du_dot_du[var_num];
1721}
1722
1723const std::set<SubdomainID> &
1724SystemBase::getSubdomainsForVar(const std::string & var_name) const
1725{
1726 return getSubdomainsForVar(getVariable(0, var_name).number());
1727}
1728
1729std::string
1731{
1732 return system().prefix_with_name() ? system().prefix() : "";
1733}
1734
1735void
1737{
1738 for (const auto & warehouse : _vars)
1739 for (const auto & [var_num, var_ptr] : warehouse.numberToVariableMap())
1740 var_ptr->sizeMatrixTagData();
1741}
1742
1743template MooseVariableFE<Real> & SystemBase::getFieldVariable<Real>(THREAD_ID tid,
1744 const std::string & var_name);
1745
1747SystemBase::getFieldVariable<RealVectorValue>(THREAD_ID tid, const std::string & var_name);
1748
1750SystemBase::getFieldVariable<RealEigenVector>(THREAD_ID tid, const std::string & var_name);
1751
1752template MooseVariableFE<Real> & SystemBase::getFieldVariable<Real>(THREAD_ID tid,
1753 unsigned int var_number);
1754
1756SystemBase::getFieldVariable<RealVectorValue>(THREAD_ID tid, unsigned int var_number);
1757
1759SystemBase::getFieldVariable<RealEigenVector>(THREAD_ID tid, unsigned int var_number);
1760
1761template MooseVariableField<Real> &
1762SystemBase::getActualFieldVariable<Real>(THREAD_ID tid, const std::string & var_name);
1763
1765SystemBase::getActualFieldVariable<RealVectorValue>(THREAD_ID tid, const std::string & var_name);
1766
1768SystemBase::getActualFieldVariable<RealEigenVector>(THREAD_ID tid, const std::string & var_name);
1769
1770template MooseVariableField<Real> &
1771SystemBase::getActualFieldVariable<Real>(THREAD_ID tid, unsigned int var_number);
1772
1774SystemBase::getActualFieldVariable<RealVectorValue>(THREAD_ID tid, unsigned int var_number);
1775
1777SystemBase::getActualFieldVariable<RealEigenVector>(THREAD_ID tid, unsigned int var_number);
1778
1779template MooseVariableFV<Real> & SystemBase::getFVVariable<Real>(THREAD_ID tid,
1780 const std::string & var_name);
boundary_id_type BoundaryID
subdomain_id_type SubdomainID
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
for(PetscInt i=0;i< nvars;++i)
char ** vars
char ** blocks
void extraSendList(std::vector< dof_id_type > &send_list, void *context)
Free function used for a libMesh callback.
Definition SystemBase.C:38
void extraSparsity(libMesh::SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *context)
Free function used for a libMesh callback.
Definition SystemBase.C:46
unsigned int n_vars
Grab all the (possibly semi)local dof indices for the variables passed in, in the system passed in.
const std::set< dof_id_type > & getDofIndices() const
void prepareNeighbor()
Definition Assembly.C:2864
An inteface for the _console for outputting to the Console object.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
std::ios_base::fmtflags flags() const
Return the current flags.
std::streamsize precision() const
Return the current precision.
void unsetf(std::ios_base::fmtflags mask) const
Unset format flags.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual bool uDotRequested()
Get boolean flag to check whether solution time derivative needs to be stored.
virtual bool uDotOldRequested()
Get boolean flag to check whether old solution time derivative needs to be stored.
virtual bool uDotDotRequested()
Get boolean flag to check whether solution second time derivative needs to be stored.
virtual bool uDotDotOldRequested()
Get boolean flag to check whether old solution second time derivative needs to be stored.
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, const InputParameters &parameters, THREAD_ID tid=0, bool print_deprecated=true)
Definition Factory.C:142
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void paramError(const std::string &param, Args... args) const
Emits a parameter error prefixed with the parameter location and object information if available.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
THREAD_ID numThreads() const
Returns the number of threads this application uses.
Definition MooseApp.h:421
Class for containing MooseEnum item information.
virtual Elem * elemPtr(const dof_id_type i)
Definition MooseMesh.C:3177
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
Definition MooseMesh.C:1678
const libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems,...
Definition MooseMesh.C:1247
Base variable class.
Class for stuff related to variables.
This class provides variable solution values for other classes/objects to bind to when looping over f...
This class provides an interface for common operations on field variables of both FE and FV types wit...
Class for stuff related to variables.
Class for scalar variables (they are different).
Base class template for functor objects.
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:213
virtual bool computingScalingJacobian() const =0
Getter for whether we're computing the scaling jacobian.
virtual const std::set< MooseVariableFieldBase * > & getActiveElementalMooseVariables(const THREAD_ID tid) const
Get the MOOSE variables to be reinited on each element.
Definition SubProblem.C:446
virtual std::set< dof_id_type > & ghostedElems()
Return the list of elements that should have their DoFs ghosted to this processor.
Definition SubProblem.h:683
virtual unsigned int numMatrixTags() const
The total number of tags.
Definition SubProblem.h:251
virtual TagName matrixTagName(TagID tag)
Retrieve the name associated with a TagID.
Definition SubProblem.C:349
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num)=0
virtual bool hasActiveElementalMooseVariables(const THREAD_ID tid) const
Whether or not a list of active elemental moose variables has been set.
Definition SubProblem.C:452
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
Create a Tag.
Definition SubProblem.C:84
virtual bool checkNonlocalCouplingRequirement() const =0
bool vectorTagNotZeroed(const TagID tag) const
Checks if a vector tag is in the list of vectors that will not be zeroed when other tagged vectors ar...
Definition SubProblem.C:147
virtual bool matrixTagExists(const TagName &tag_name) const
Check to see if a particular Tag exists.
Definition SubProblem.C:320
virtual bool vectorTagExists(const TagID tag_id) const
Check to see if a particular Tag exists.
Definition SubProblem.h:204
void addFunctor(const std::string &name, const Moose::FunctorBase< T > &functor, const THREAD_ID tid)
add a functor to the problem functor container
Base class for a system (of equations)
Definition SystemBase.h:87
std::unique_ptr< NumericVector< Number > > _serialized_solution
Serialized version of the solution vector, or nullptr if a serialized solution is not needed.
void zeroTaggedVectors(const std::set< TagID > &tags)
Zero all vectors for given tags.
Definition SystemBase.C:695
virtual void addVariableToZeroOnJacobian(std::string var_name)
Adds this variable to the list of variables to be zeroed during each Jacobian evaluation.
Definition SystemBase.C:182
void zeroTaggedVector(const TagID tag)
Zero vector with the given tag.
Definition SystemBase.C:676
virtual void zeroVariables(std::vector< std::string > &vars_to_be_zeroed)
Zero out the solution for the list of variables passed in.
Definition SystemBase.C:202
NumericVector< Number > * _u_dot
solution vector for u^dot
virtual void prepareNeighbor(THREAD_ID tid)
Prepare the system for use.
Definition SystemBase.C:326
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
virtual void reinitNode(const Node *node, THREAD_ID tid)
Reinit nodal assembly info.
Definition SystemBase.C:400
virtual void addVariableToZeroOnResidual(std::string var_name)
Adds this variable to the list of variables to be zeroed during each residual evaluation.
Definition SystemBase.C:176
virtual void copySolutionsBackwards()
Copy current solution into old and older.
virtual void zeroVariablesForJacobian()
Zero out the solution for the variables that were registered as needing to have their solutions zeroe...
Definition SystemBase.C:237
virtual void augmentSparsity(libMesh::SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz)=0
Will modify the sparsity pattern to add logical geometric connections.
bool _solution_states_initialized
Whether or not the solution states have been initialized.
virtual libMesh::SparseMatrix< Number > & getMatrix(TagID tag)
Get a raw SparseMatrix.
MooseApp & _app
virtual std::set< TagID > defaultMatrixTags() const
Get the default matrix tags associted with this system.
Definition SystemBase.h:350
virtual void deactivateAllMatrixTags()
Make matrices inactive.
virtual NumericVector< Number > & solutionInternal() const =0
Internal getter for solution owned by libMesh.
virtual void reinitElem(const Elem *elem, THREAD_ID tid)
Reinit an element assembly info.
Definition SystemBase.C:342
virtual void reinitNodes(const std::vector< dof_id_type > &nodes, THREAD_ID tid)
Reinit variables at a set of nodes.
Definition SystemBase.C:424
bool _verbose
True if printing out additional information.
void copyOldSolutions()
Copy the solution back in time (older -> old, etc).
FEProblemBase & _fe_problem
the governing finite element/volume problem
virtual void reinitNeighbor(const Elem *elem, THREAD_ID tid)
Compute the values of the variables at all the current points.
Definition SystemBase.C:384
TagName oldSolutionStateVectorName(const unsigned int, Moose::SolutionIterationType iteration_type) const
Gets the vector name used for an old (not current) solution state.
const std::set< SubdomainID > & getSubdomainsForVar(unsigned int var_number) const
Definition SystemBase.h:794
virtual void subdomainSetup()
virtual void reinitNeighborFace(const Elem *elem, unsigned int side, THREAD_ID tid)
Compute the values of the variables at all the current points.
Definition SystemBase.C:376
std::vector< std::shared_ptr< TimeIntegrator > > _time_integrators
Time integrator.
void addTimeIntegrator(const std::string &type, const std::string &name, InputParameters &parameters)
std::string prefix() const
std::vector< std::string > _vars_to_be_zeroed_on_residual
bool hasVector(const std::string &tag_name) const
Check if the named vector exists in the system.
Definition SystemBase.C:924
NumericVector< Number > * _u_dotdot
solution vector for u^dotdot
virtual unsigned int nVariables() const
Get the number of variables in this system.
Definition SystemBase.C:891
MooseVariableFE< T > & getFieldVariable(THREAD_ID tid, const std::string &var_name)
Gets a reference to a variable of with specified name.
Definition SystemBase.C:113
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition SystemBase.C:92
virtual NumericVector< Number > * solutionUDot()
Definition SystemBase.h:292
virtual bool isArrayVariable(const std::string &var_name) const
If a variable is an array variable.
Definition SystemBase.C:864
virtual void augmentSendList(std::vector< dof_id_type > &send_list)
Will modify the send_list to add all of the extra ghosted dofs for this system.
Definition SystemBase.C:454
virtual void reinitScalars(THREAD_ID tid, bool reinit_for_derivative_reordering=false)
Reinit scalar varaibles.
Definition SystemBase.C:446
unsigned int number() const
Gets the number of this system.
virtual void saveOldSolutions()
Save the old and older solutions.
Definition SystemBase.C:512
virtual void restoreOldSolutions()
Restore the old and older solutions when the saved solutions present.
Definition SystemBase.C:543
virtual bool isScalarVariable(unsigned int var_name) const
Definition SystemBase.C:885
Factory & _factory
std::vector< libMesh::SparseMatrix< Number > * > _tagged_matrices
Tagged matrices (pointer)
void restoreStateHistory()
Restore solution vectors and additional system-owned state together.
virtual void activateAllMatrixTags()
Make all existing matrices active.
unsigned int nFieldVariables() const
Get the number of field variables in this system.
Definition SystemBase.C:900
void advanceStateHistory(Moose::SolutionIterationType iteration_type)
Advance solution vectors and additional system-owned state together.
virtual void addVariableToCopy(const std::string &dest_name, const std::string &source_name, const std::string &timestep)
Add info about variable that will be copied.
const std::vector< VariableName > & getVariableNames() const
Definition SystemBase.h:893
void removeVector(const std::string &name)
Remove a vector from the system with the given name.
virtual void zeroVariablesForResidual()
Zero out the solution for the variables that were registered as needing to have their solutions zeroe...
Definition SystemBase.C:231
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &parameters)
Canonical method for adding a variable.
Definition SystemBase.C:720
MooseVariableFV< T > & getFVVariable(THREAD_ID tid, const std::string &var_name)
Return a finite volume variable.
Definition SystemBase.C:127
std::unordered_map< TagID, libMesh::SparseMatrix< Number > * > _active_tagged_matrices
Active tagged matrices. A matrix is active if its tag-matrix pair is present in the map....
virtual void addDotVectors()
Add u_dot, u_dotdot, u_dot_old and u_dotdot_old vectors if requested by the time integrator.
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
Definition SystemBase.C:933
virtual void needSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time, libMesh::ParallelType parallel_type=GHOSTED)
Registers that the solution state state is needed.
const std::vector< MooseVariableFieldBase * > & getVariables(THREAD_ID tid)
Definition SystemBase.h:782
virtual bool matrixTagActive(TagID tag) const
If or not a matrix tag is active.
virtual void customSetup(const ExecFlagType &exec_type)
NumericVector< Number > & solutionOld()
Definition SystemBase.h:216
const TimeIntegrator & getTimeIntegrator(const unsigned int var_num) const
Retrieve the time integrator that integrates the given variable's equation.
unsigned int nFVVariables() const
Get the number of finite volume variables in this system.
Definition SystemBase.C:910
virtual void disassociateMatrixFromTag(libMesh::SparseMatrix< Number > &matrix, TagID tag)
Disassociate a matrix from a tag.
void setActiveScalarVariableCoupleableVectorTags(const std::set< TagID > &vtags, THREAD_ID tid)
Set the active vector tags for the scalar variables.
NumericVector< Real > * _saved_dotdot_old
void copyStateHistoryBackwards()
Copy solution vectors and additional system-owned state into older states.
void setVariableGlobalDoFs(const std::string &var_name)
set all the global dof indices for a variable
Definition SystemBase.C:188
virtual void initialSetup()
Setup Functions.
virtual void initSolutionState()
Initializes the solution state.
virtual void timestepSetup()
virtual void associateVectorToTag(NumericVector< Number > &vec, TagID tag)
Associate a vector for a given tag.
Definition SystemBase.C:981
virtual void jacobianSetup()
virtual void residualSetup()
MooseVariableField< T > & getActualFieldVariable(THREAD_ID tid, const std::string &var_name)
Returns a field variable pointer - this includes finite volume variables.
Definition SystemBase.C:120
bool computingScalingJacobian() const
Whether we are computing an initial Jacobian for automatic variable scaling.
std::vector< bool > _matrix_tag_active_flags
Active flags for tagged matrices.
virtual void reinitNodesNeighbor(const std::vector< dof_id_type > &nodes, THREAD_ID tid)
Reinit variables at a set of neighbor nodes.
Definition SystemBase.C:435
std::vector< Real > _du_dot_du
Derivative of time derivative of u with respect to uj.
virtual void disassociateDefaultVectorTags()
Disassociate the vectors associated with the default vector tags of this system.
virtual void restoreSolutions()
Restore current solutions (call after your solve failed)
libMesh::ParallelType solutionStateParallelType(const unsigned int state, const Moose::SolutionIterationType iteration_type) const
Returns the parallel type of the given solution state.
virtual void reinitLowerD(THREAD_ID tid)
Compute the values of the variables on the lower dimensional element.
Definition SystemBase.C:392
virtual NumericVector< Number > * solutionUDotOld()
Definition SystemBase.h:294
virtual void disassociateVectorFromTag(NumericVector< Number > &vec, TagID tag)
Disassociate a given vector from a given tag.
Definition SystemBase.C:993
virtual void prepare(THREAD_ID tid)
Prepare the system for use.
Definition SystemBase.C:258
SystemBase(SubProblem &subproblem, FEProblemBase &fe_problem, const std::string &name, Moose::VarKindType var_kind)
Definition SystemBase.C:55
void closeTaggedVectors(const std::set< TagID > &tags)
Close all vectors for given tags.
Definition SystemBase.C:669
std::size_t getNumSolutionStates(const Moose::SolutionIterationType iteration_type) const
Get the number of solution states (0 = current, 1 = current + old, ...) for the given iteration type.
virtual const std::set< SubdomainID > * getVariableBlocks(unsigned int var_number)
Get the block where a variable of this system is defined.
Definition SystemBase.C:166
virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a scalar variable with specified number.
Definition SystemBase.C:147
virtual bool hasScalarVariable(const std::string &var_name) const
Definition SystemBase.C:876
virtual void reinitElemFace(const Elem *elem, unsigned int side, THREAD_ID tid)
Reinit assembly info for a side of an element.
Definition SystemBase.C:368
virtual void reinitNodeFace(const Node *node, BoundaryID bnd_id, THREAD_ID tid)
Reinit nodal assembly info on a face.
Definition SystemBase.C:412
std::vector< VariableWarehouse > _vars
Variable warehouses (one for each thread)
std::vector< NumericVector< Number > * > _tagged_vectors
Tagged vectors (pointer)
void copyPreviousSolutions(const Moose::SolutionIterationType iteration_type)
Copy a specific type of solution back in time (current -> old -> older, etc).
THREAD_ID numThreads() const
Definition SystemBase.C:89
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
Definition SystemBase.C:851
void closeTaggedMatrices(const std::set< TagID > &tags)
Close all matrices associated the tags.
virtual const NumericVector< Number > * solutionPreviousNewton() const
const std::vector< std::shared_ptr< TimeIntegrator > > & getTimeIntegrators()
const std::vector< NumericVector< Number > * > & getSolutionStates(const Moose::SolutionIterationType iteration_type) const
Get all of the solution states (current, old, ...) for the given iteration type.
virtual const Number & duDotDu(unsigned int var_num=0) const
void flushTaggedMatrices(const std::set< TagID > &tags)
flushes all matrices associated to tags.
SubProblem & _subproblem
The subproblem for whom this class holds variable data, etc; this can either be the governing finite ...
void applyScalingFactors(const std::vector< Real > &inverse_scaling_factors)
Applies scaling factors to the system's variables.
NumericVector< Real > * _saved_dot_old
virtual void restoreAdditionalStates()
Restore system-owned state not represented by solution vectors.
virtual void associateMatrixToTag(libMesh::SparseMatrix< Number > &matrix, TagID tag)
Associate a matrix to a tag.
libMesh::SparseMatrix< Number > & addMatrix(TagID tag)
Adds a matrix with a given tag.
Definition SystemBase.C:570
void clearAllDofIndices()
Clear all dof indices from moose variables.
NumericVector< Number > * _u_dotdot_old
old solution vector for u^dotdot
virtual const std::string & name() const
virtual bool hasMatrix(TagID tag) const
Check if the tagged matrix exists in the system.
Definition SystemBase.h:391
void copyTimeIntegrators(const SystemBase &other_sys)
Copy time integrators from another system.
virtual NumericVector< Number > & solutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time)
Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
unsigned int _max_var_number
Maximum variable number.
virtual void disassociateDefaultMatrixTags()
Disassociate the matrices associated with the default matrix tags of this system.
void copyVars(libMesh::ExodusII_IO &io)
void removeMatrix(TagID tag)
Removes a matrix with a given tag.
Definition SystemBase.C:590
void setActiveVariableCoupleableVectorTags(const std::set< TagID > &vtags, THREAD_ID tid)
Set the active vector tags for the variables.
bool _skip_next_solution_to_old_copy
Whether to skip the next copy from the solution to the old vector.
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
std::map< unsigned int, std::set< SubdomainID > > _var_map
Map of variables (variable id -> array of subdomains where it lives)
virtual bool hasSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time) const
Whether or not the system has the solution state (0 = current, 1 = old, 2 = older,...
std::vector< VarCopyInfo > _var_to_copy
NumericVector< Number > & solution()
Definition SystemBase.h:215
NumericVector< Number > * _u_dot_old
old solution vector for u^dot
std::vector< NumericVector< Number > * > _saved_solution_states
The saved solution states (0 = current, 1 = old, 2 = older, etc)
virtual NumericVector< Number > * solutionUDotDotOld()
Definition SystemBase.h:295
void sizeVariableMatrixData()
size the matrix data for each variable for the number of matrix tags we have
virtual void copyAdditionalStateBackwards(Moose::SolutionIterationType, bool)
Copy system-owned state not represented by solution vectors.
std::vector< std::string > _vars_to_be_zeroed_on_jacobian
std::vector< dof_id_type > _var_all_dof_indices
Container for the dof indices of a given variable.
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition SystemBase.h:789
const TimeIntegrator * queryTimeIntegrator(const unsigned int var_num) const
Retrieve the time integrator that integrates the given variable's equation.
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const libMesh::ParallelType type)
Adds a solution length vector to the system.
Definition SystemBase.C:608
virtual libMesh::Order getMinQuadratureOrder()
Get minimal quadrature order needed for integrating variables in this system.
Definition SystemBase.C:243
void update()
Update the system (doing libMesh magic)
virtual void prepareFace(THREAD_ID tid, bool resize_data)
Prepare the system for use on sides.
Definition SystemBase.C:281
virtual std::set< TagID > defaultVectorTags() const
Get the default vector tags associated with this system.
Definition SystemBase.h:343
void closeTaggedVector(const TagID tag)
Close vector with the given tag.
Definition SystemBase.C:651
virtual void solve()
Solve the system (using libMesh magic)
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
virtual NumericVector< Number > * solutionUDotDot()
Definition SystemBase.h:293
MooseMesh & _mesh
virtual NumericVector< Number > & serializedSolution()
Returns a reference to a serialized version of the solution vector for this subproblem.
std::vector< std::vector< MooseVariableFieldBase * > > _numbered_vars
Map variable number to its pointer.
virtual void prepareLowerD(THREAD_ID tid)
Prepare the system for use for lower dimensional elements.
Definition SystemBase.C:334
Base class for time integrators.
virtual void set(const numeric_index_type i, const T value)=0
virtual void close()=0
virtual void zero()=0
const Parallel::Communicator & _communicator
const Parallel::Communicator & comm() const
virtual void close()=0
virtual void flush()
SparseMatrix< Number > & add_matrix(std::string_view mat_name, ParallelType type=PARALLEL, MatrixBuildType mat_build_type=MatrixBuildType::AUTOMATIC)
const std::string & name() const
void remove_matrix(std::string_view mat_name)
void remove_vector(std::string_view vec_name)
const FEType & variable_type(const unsigned int i) const
void prefix_with_name(bool value)
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
unsigned int add_variable_array(const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
virtual void solve()
virtual void update()
bool has_static_condensation() const
std::string prefix() const
const DofMap & get_dof_map() const
unsigned int number() const
const NumericVector< Number > & get_vector(std::string_view vec_name) const
bool have_vector(std::string_view vec_name) const
unsigned int n_components() const
unsigned int number() const
MeshBase & mesh
libMesh::FEType variableFEType(const InputParameters &params)
Definition MooseUtils.C:98
const TagName PREVIOUS_MULTISYSTEM_FP_SOLUTION_TAG
Definition MooseTypes.C:30
const TagName OLDER_SOLUTION_TAG
Definition MooseTypes.C:27
@ VECTOR_TAG_SOLUTION
const TagName PREVIOUS_NL_SOLUTION_TAG
Definition MooseTypes.C:28
const TagName PREVIOUS_MULTIAPP_FP_SOLUTION_TAG
Definition MooseTypes.C:29
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:65
const TagName OLD_SOLUTION_TAG
Definition MooseTypes.C:26
SolutionIterationType
Definition MooseTypes.h:270
VarKindType
Framework-wide stuff.
Definition MooseTypes.h:769
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...
Information about variables that will be copied.
Definition SystemBase.h:68