Line data Source code
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 : #pragma once
11 :
12 : #ifdef MOOSE_KOKKOS_ENABLED
13 : #include "KokkosAssembly.h"
14 : #include "KokkosSystem.h"
15 : #endif
16 :
17 : // MOOSE includes
18 : #include "SubProblem.h"
19 : #include "GeometricSearchData.h"
20 : #include "MeshDivision.h"
21 : #include "ReporterData.h"
22 : #include "Adaptivity.h"
23 : #include "InitialConditionWarehouse.h"
24 : #include "FVInitialConditionWarehouse.h"
25 : #include "ScalarInitialConditionWarehouse.h"
26 : #include "Restartable.h"
27 : #include "SolverParams.h"
28 : #include "PetscSupport.h"
29 : #include "MooseApp.h"
30 : #include "ExecuteMooseObjectWarehouse.h"
31 : #include "MaterialWarehouse.h"
32 : #include "MooseVariableFE.h"
33 : #include "MultiAppTransfer.h"
34 : #include "Postprocessor.h"
35 : #include "HashMap.h"
36 : #include "VectorPostprocessor.h"
37 : #include "PerfGraphInterface.h"
38 : #include "Attributes.h"
39 : #include "MooseObjectWarehouse.h"
40 : #include "MaterialPropertyRegistry.h"
41 : #include "RestartableEquationSystems.h"
42 : #include "SolutionInvalidity.h"
43 : #include "PetscSupport.h"
44 :
45 : #include "libmesh/enum_quadrature_type.h"
46 : #include "libmesh/equation_systems.h"
47 :
48 : #include <unordered_map>
49 : #include <memory>
50 :
51 : // Forward declarations
52 : class AuxiliarySystem;
53 : class DisplacedProblem;
54 : class MooseMesh;
55 : class NonlinearSystemBase;
56 : class LinearSystem;
57 : class SolverSystem;
58 : class NonlinearSystem;
59 : class RandomInterface;
60 : class RandomData;
61 : class MeshChangedInterface;
62 : class MeshDisplacedInterface;
63 : class MultiMooseEnum;
64 : class MaterialPropertyStorage;
65 : class MaterialData;
66 : class MooseEnum;
67 : class MortarInterfaceWarehouse;
68 : class Assembly;
69 : class JacobianBlock;
70 : class Control;
71 : class MultiApp;
72 : class TransientMultiApp;
73 : class ScalarInitialCondition;
74 : class Indicator;
75 : class InternalSideIndicatorBase;
76 : class Marker;
77 : class Material;
78 : class Transfer;
79 : class XFEMInterface;
80 : class SideUserObject;
81 : class NodalUserObject;
82 : class ElementUserObject;
83 : class InternalSideUserObject;
84 : class InterfaceUserObject;
85 : class GeneralUserObject;
86 : class Positions;
87 : class Function;
88 : class Distribution;
89 : class Sampler;
90 : class KernelBase;
91 : class IntegratedBCBase;
92 : class LineSearch;
93 : class UserObject;
94 : class AutomaticMortarGeneration;
95 : class VectorPostprocessor;
96 : class Convergence;
97 : class MooseAppCoordTransform;
98 : class MortarUserObject;
99 : class SolutionInvalidity;
100 :
101 : #ifdef MOOSE_KOKKOS_ENABLED
102 : namespace Moose::Kokkos
103 : {
104 : class MaterialPropertyStorage;
105 : }
106 : #endif
107 :
108 : // libMesh forward declarations
109 : namespace libMesh
110 : {
111 : class CouplingMatrix;
112 : class NonlinearImplicitSystem;
113 : class LinearImplicitSystem;
114 : } // namespace libMesh
115 :
116 : enum class MooseLinearConvergenceReason
117 : {
118 : ITERATING = 0,
119 : // CONVERGED_RTOL_NORMAL = 1,
120 : // CONVERGED_ATOL_NORMAL = 9,
121 : CONVERGED_RTOL = 2,
122 : CONVERGED_ATOL = 3,
123 : CONVERGED_ITS = 4,
124 : // CONVERGED_CG_NEG_CURVE = 5,
125 : // CONVERGED_CG_CONSTRAINED = 6,
126 : // CONVERGED_STEP_LENGTH = 7,
127 : // CONVERGED_HAPPY_BREAKDOWN = 8,
128 : DIVERGED_NULL = -2,
129 : // DIVERGED_ITS = -3,
130 : // DIVERGED_DTOL = -4,
131 : // DIVERGED_BREAKDOWN = -5,
132 : // DIVERGED_BREAKDOWN_BICG = -6,
133 : // DIVERGED_NONSYMMETRIC = -7,
134 : // DIVERGED_INDEFINITE_PC = -8,
135 : DIVERGED_NANORINF = -9,
136 : // DIVERGED_INDEFINITE_MAT = -10
137 : DIVERGED_PCSETUP_FAILED = -11
138 : };
139 :
140 : /**
141 : * Specialization of SubProblem for solving nonlinear equations plus auxiliary equations
142 : *
143 : */
144 : class FEProblemBase : public SubProblem, public Restartable
145 : {
146 : public:
147 : static InputParameters validParams();
148 :
149 : FEProblemBase(const InputParameters & parameters);
150 : virtual ~FEProblemBase();
151 :
152 : enum class CoverageCheckMode
153 : {
154 : FALSE,
155 : TRUE,
156 : OFF,
157 : ON,
158 : SKIP_LIST,
159 : ONLY_LIST,
160 : };
161 :
162 1642990 : virtual libMesh::EquationSystems & es() override { return _req.set().es(); }
163 77399370 : virtual MooseMesh & mesh() override { return _mesh; }
164 2485947328 : virtual const MooseMesh & mesh() const override { return _mesh; }
165 : const MooseMesh & mesh(bool use_displaced) const override;
166 :
167 : void setCoordSystem(const std::vector<SubdomainName> & blocks, const MultiMooseEnum & coord_sys);
168 : void setAxisymmetricCoordAxis(const MooseEnum & rz_coord_axis);
169 :
170 : /**
171 : * Set the coupling between variables
172 : * TODO: allow user-defined coupling
173 : * @param type Type of coupling
174 : */
175 : void setCoupling(Moose::CouplingType type);
176 :
177 527777 : Moose::CouplingType coupling() const { return _coupling; }
178 :
179 : /**
180 : * Set custom coupling matrix
181 : * @param cm coupling matrix to be set
182 : * @param nl_sys_num which nonlinear system we are setting the coupling matrix for
183 : */
184 : void setCouplingMatrix(std::unique_ptr<libMesh::CouplingMatrix> cm,
185 : const unsigned int nl_sys_num);
186 :
187 : // DEPRECATED METHOD
188 : void setCouplingMatrix(libMesh::CouplingMatrix * cm, const unsigned int nl_sys_num);
189 :
190 : const libMesh::CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const override;
191 :
192 : /// Set custom coupling matrix for variables requiring nonlocal contribution
193 : void setNonlocalCouplingMatrix();
194 :
195 : bool
196 : areCoupled(const unsigned int ivar, const unsigned int jvar, const unsigned int nl_sys_num) const;
197 :
198 : /**
199 : * Whether or not MOOSE will perform a user object/auxiliary kernel state check
200 : */
201 : bool hasUOAuxStateCheck() const { return _uo_aux_state_check; }
202 :
203 : /**
204 : * Return a flag to indicate whether we are executing user objects and auxliary kernels for state
205 : * check
206 : * Note: This function can return true only when hasUOAuxStateCheck() returns true, i.e. the check
207 : * has been activated by users through Problem/check_uo_aux_state input parameter.
208 : */
209 4204 : bool checkingUOAuxState() const { return _checking_uo_aux_state; }
210 :
211 : /**
212 : * Whether to trust the user coupling matrix even if we want to do things like be paranoid and
213 : * create a full coupling matrix. See https://github.com/idaholab/moose/issues/16395 for detailed
214 : * background
215 : */
216 : void trustUserCouplingMatrix();
217 :
218 : std::vector<std::pair<MooseVariableFEBase *, MooseVariableFEBase *>> &
219 : couplingEntries(const THREAD_ID tid, const unsigned int nl_sys_num);
220 : std::vector<std::pair<MooseVariableFEBase *, MooseVariableFEBase *>> &
221 : nonlocalCouplingEntries(const THREAD_ID tid, const unsigned int nl_sys_num);
222 :
223 : virtual bool hasVariable(const std::string & var_name) const override;
224 : // NOTE: hasAuxiliaryVariable defined in parent class
225 : bool hasSolverVariable(const std::string & var_name) const;
226 : using SubProblem::getVariable;
227 : virtual const MooseVariableFieldBase &
228 : getVariable(const THREAD_ID tid,
229 : const std::string & var_name,
230 : Moose::VarKindType expected_var_type = Moose::VarKindType::VAR_ANY,
231 : Moose::VarFieldType expected_var_field_type =
232 : Moose::VarFieldType::VAR_FIELD_ANY) const override;
233 : MooseVariableFieldBase & getActualFieldVariable(const THREAD_ID tid,
234 : const std::string & var_name) override;
235 : virtual MooseVariable & getStandardVariable(const THREAD_ID tid,
236 : const std::string & var_name) override;
237 : virtual VectorMooseVariable & getVectorVariable(const THREAD_ID tid,
238 : const std::string & var_name) override;
239 : virtual ArrayMooseVariable & getArrayVariable(const THREAD_ID tid,
240 : const std::string & var_name) override;
241 :
242 : virtual bool hasScalarVariable(const std::string & var_name) const override;
243 : virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid,
244 : const std::string & var_name) override;
245 : virtual libMesh::System & getSystem(const std::string & var_name) override;
246 :
247 : /// Get the RestartableEquationSystems object
248 : const RestartableEquationSystems & getRestartableEquationSystems() const;
249 :
250 : /**
251 : * Set the MOOSE variables to be reinited on each element.
252 : * @param moose_vars A set of variables that need to be reinited each time reinit() is called.
253 : *
254 : * @param tid The thread id
255 : */
256 : virtual void setActiveElementalMooseVariables(const std::set<MooseVariableFEBase *> & moose_vars,
257 : const THREAD_ID tid) override;
258 :
259 : /**
260 : * Clear the active elemental MooseVariableFEBase. If there are no active variables then they
261 : * will all be reinited. Call this after finishing the computation that was using a restricted set
262 : * of MooseVariableFEBases
263 : *
264 : * @param tid The thread id
265 : */
266 : virtual void clearActiveElementalMooseVariables(const THREAD_ID tid) override;
267 :
268 : virtual void clearActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid) override;
269 :
270 : virtual void clearActiveFEVariableCoupleableVectorTags(const THREAD_ID tid) override;
271 :
272 : virtual void setActiveFEVariableCoupleableVectorTags(std::set<TagID> & vtags,
273 : const THREAD_ID tid) override;
274 :
275 : virtual void setActiveFEVariableCoupleableMatrixTags(std::set<TagID> & mtags,
276 : const THREAD_ID tid) override;
277 :
278 : virtual void clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid) override;
279 :
280 : virtual void clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid) override;
281 :
282 : virtual void setActiveScalarVariableCoupleableVectorTags(std::set<TagID> & vtags,
283 : const THREAD_ID tid) override;
284 :
285 : virtual void setActiveScalarVariableCoupleableMatrixTags(std::set<TagID> & mtags,
286 : const THREAD_ID tid) override;
287 :
288 : virtual void createQRules(libMesh::QuadratureType type,
289 : libMesh::Order order,
290 : libMesh::Order volume_order = libMesh::INVALID_ORDER,
291 : libMesh::Order face_order = libMesh::INVALID_ORDER,
292 : SubdomainID block = Moose::ANY_BLOCK_ID,
293 : bool allow_negative_qweights = true);
294 :
295 : /**
296 : * Increases the element/volume quadrature order for the specified mesh
297 : * block if and only if the current volume quadrature order is lower. This
298 : * can only cause the quadrature level to increase. If volume_order is
299 : * lower than or equal to the current volume/elem quadrature rule order,
300 : * then nothing is done (i.e. this function is idempotent).
301 : */
302 : void bumpVolumeQRuleOrder(libMesh::Order order, SubdomainID block);
303 :
304 : void bumpAllQRuleOrder(libMesh::Order order, SubdomainID block);
305 :
306 : /**
307 : * @return The maximum number of quadrature points in use on any element in this problem.
308 : */
309 : unsigned int getMaxQps() const;
310 :
311 : /**
312 : * @return The maximum order for all scalar variables in this problem's systems.
313 : */
314 : libMesh::Order getMaxScalarOrder() const;
315 :
316 : /**
317 : * @return Flag indicating nonlocal coupling exists or not.
318 : */
319 : void checkNonlocalCoupling();
320 : void checkUserObjectJacobianRequirement(THREAD_ID tid);
321 : void setVariableAllDoFMap(const std::vector<const MooseVariableFEBase *> & moose_vars);
322 :
323 : const std::vector<const MooseVariableFEBase *> &
324 1692 : getUserObjectJacobianVariables(const THREAD_ID tid) const
325 : {
326 1692 : return _uo_jacobian_moose_vars[tid];
327 : }
328 :
329 : virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) override;
330 : virtual const Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) const override;
331 :
332 : #ifdef MOOSE_KOKKOS_ENABLED
333 7970 : Moose::Kokkos::Assembly & kokkosAssembly() { return _kokkos_assembly; }
334 : const Moose::Kokkos::Assembly & kokkosAssembly() const { return _kokkos_assembly; }
335 : #endif
336 :
337 : /**
338 : * Returns a list of all the variables in the problem (both from the NL and Aux systems.
339 : */
340 : virtual std::vector<VariableName> getVariableNames();
341 :
342 : void initialSetup() override;
343 : void checkDuplicatePostprocessorVariableNames();
344 : void timestepSetup() override;
345 : void customSetup(const ExecFlagType & exec_type) override;
346 : void residualSetup() override;
347 : void jacobianSetup() override;
348 :
349 : virtual void prepare(const Elem * elem, const THREAD_ID tid) override;
350 : virtual void prepareFace(const Elem * elem, const THREAD_ID tid) override;
351 : virtual void prepare(const Elem * elem,
352 : unsigned int ivar,
353 : unsigned int jvar,
354 : const std::vector<dof_id_type> & dof_indices,
355 : const THREAD_ID tid) override;
356 :
357 : virtual void setCurrentSubdomainID(const Elem * elem, const THREAD_ID tid) override;
358 : virtual void
359 : setNeighborSubdomainID(const Elem * elem, unsigned int side, const THREAD_ID tid) override;
360 : virtual void setNeighborSubdomainID(const Elem * elem, const THREAD_ID tid);
361 : virtual void prepareAssembly(const THREAD_ID tid) override;
362 :
363 : virtual void addGhostedElem(dof_id_type elem_id) override;
364 : virtual void addGhostedBoundary(BoundaryID boundary_id) override;
365 : virtual void ghostGhostedBoundaries() override;
366 :
367 : virtual void sizeZeroes(unsigned int size, const THREAD_ID tid);
368 : virtual bool reinitDirac(const Elem * elem, const THREAD_ID tid) override;
369 :
370 : virtual void reinitElem(const Elem * elem, const THREAD_ID tid) override;
371 : virtual void reinitElemPhys(const Elem * elem,
372 : const std::vector<Point> & phys_points_in_elem,
373 : const THREAD_ID tid) override;
374 : void reinitElemFace(const Elem * elem, unsigned int side, BoundaryID, const THREAD_ID tid);
375 : virtual void reinitElemFace(const Elem * elem, unsigned int side, const THREAD_ID tid) override;
376 : virtual void reinitLowerDElem(const Elem * lower_d_elem,
377 : const THREAD_ID tid,
378 : const std::vector<Point> * const pts = nullptr,
379 : const std::vector<Real> * const weights = nullptr) override;
380 : virtual void reinitNode(const Node * node, const THREAD_ID tid) override;
381 : virtual void reinitNodeFace(const Node * node, BoundaryID bnd_id, const THREAD_ID tid) override;
382 : virtual void reinitNodes(const std::vector<dof_id_type> & nodes, const THREAD_ID tid) override;
383 : virtual void reinitNodesNeighbor(const std::vector<dof_id_type> & nodes,
384 : const THREAD_ID tid) override;
385 : virtual void reinitNeighbor(const Elem * elem, unsigned int side, const THREAD_ID tid) override;
386 : virtual void reinitNeighborPhys(const Elem * neighbor,
387 : unsigned int neighbor_side,
388 : const std::vector<Point> & physical_points,
389 : const THREAD_ID tid) override;
390 : virtual void reinitNeighborPhys(const Elem * neighbor,
391 : const std::vector<Point> & physical_points,
392 : const THREAD_ID tid) override;
393 : virtual void
394 : reinitElemNeighborAndLowerD(const Elem * elem, unsigned int side, const THREAD_ID tid) override;
395 : virtual void reinitScalars(const THREAD_ID tid,
396 : bool reinit_for_derivative_reordering = false) override;
397 : virtual void reinitOffDiagScalars(const THREAD_ID tid) override;
398 :
399 : /// Fills "elems" with the elements that should be looped over for Dirac Kernels
400 : virtual void getDiracElements(std::set<const Elem *> & elems) override;
401 : virtual void clearDiracInfo() override;
402 :
403 : virtual void subdomainSetup(SubdomainID subdomain, const THREAD_ID tid);
404 : virtual void neighborSubdomainSetup(SubdomainID subdomain, const THREAD_ID tid);
405 :
406 : virtual void newAssemblyArray(std::vector<std::shared_ptr<SolverSystem>> & solver_systems);
407 : virtual void initNullSpaceVectors(const InputParameters & parameters,
408 : std::vector<std::shared_ptr<NonlinearSystemBase>> & nl);
409 :
410 : virtual void init() override;
411 : virtual void solve(const unsigned int nl_sys_num);
412 :
413 : #ifdef MOOSE_KOKKOS_ENABLED
414 : /**
415 : * Construct Kokkos assembly and systems and allocate Kokkos material property storages
416 : */
417 : void initKokkos();
418 : #endif
419 :
420 : /**
421 : * Build and solve a linear system
422 : * @param linear_sys_num The number of the linear system (1,..,num. of lin. systems)
423 : * @param po The petsc options for the solve, if not supplied, the defaults are used
424 : */
425 : virtual void solveLinearSystem(const unsigned int linear_sys_num,
426 : const Moose::PetscSupport::PetscOptions * po = nullptr);
427 :
428 : ///@{
429 : /**
430 : * In general, {evaluable elements} >= {local elements} U {algebraic ghosting elements}. That is,
431 : * the number of evaluable elements does NOT necessarily equal to the number of local and
432 : * algebraic ghosting elements. For example, if using a Lagrange basis for all variables,
433 : * if a non-local, non-algebraically-ghosted element is surrounded by neighbors which are
434 : * local or algebraically ghosted, then all the nodal (Lagrange) degrees of freedom associated
435 : * with the non-local, non-algebraically-ghosted element will be evaluable, and hence that
436 : * element will be considered evaluable.
437 : *
438 : * getNonlinearEvaluableElementRange() returns the evaluable element range based on the nonlinear
439 : * system dofmap;
440 : * getAuxliaryEvaluableElementRange() returns the evaluable element range based on the auxiliary
441 : * system dofmap;
442 : * getEvaluableElementRange() returns the element range that is evaluable based on both the
443 : * nonlinear dofmap and the auxliary dofmap.
444 : */
445 : const libMesh::ConstElemRange & getEvaluableElementRange();
446 : const libMesh::ConstElemRange & getNonlinearEvaluableElementRange();
447 : ///@}
448 :
449 : ///@{
450 : /**
451 : * These are the element and nodes that contribute to the jacobian and
452 : * residual for this local processor.
453 : *
454 : * getCurrentAlgebraicElementRange() returns the element range that contributes to the
455 : * system
456 : * getCurrentAlgebraicNodeRange() returns the node range that contributes to the
457 : * system
458 : * getCurrentAlgebraicBndNodeRange returns the boundary node ranges that contributes
459 : * to the system
460 : */
461 : const libMesh::ConstElemRange & getCurrentAlgebraicElementRange();
462 : const libMesh::ConstNodeRange & getCurrentAlgebraicNodeRange();
463 : const ConstBndNodeRange & getCurrentAlgebraicBndNodeRange();
464 : ///@}
465 :
466 : ///@{
467 : /**
468 : * These functions allow setting custom ranges for the algebraic elements, nodes,
469 : * and boundary nodes that contribute to the jacobian and residual for this local
470 : * processor.
471 : *
472 : * setCurrentAlgebraicElementRange() sets the element range that contributes to the
473 : * system. A nullptr will reset the range to use the mesh's range.
474 : *
475 : * setCurrentAlgebraicNodeRange() sets the node range that contributes to the
476 : * system. A nullptr will reset the range to use the mesh's range.
477 : *
478 : * setCurrentAlgebraicBndNodeRange() sets the boundary node range that contributes
479 : * to the system. A nullptr will reset the range to use the mesh's range.
480 : *
481 : * @param range A pointer to the const range object representing the algebraic
482 : * elements, nodes, or boundary nodes.
483 : */
484 : void setCurrentAlgebraicElementRange(libMesh::ConstElemRange * range);
485 : void setCurrentAlgebraicNodeRange(libMesh::ConstNodeRange * range);
486 : void setCurrentAlgebraicBndNodeRange(ConstBndNodeRange * range);
487 : ///@}
488 :
489 : /**
490 : * Set an exception, which is stored at this point by toggling a member variable in
491 : * this class, and which must be followed up with by a call to
492 : * checkExceptionAndStopSolve().
493 : *
494 : * @param message The error message describing the exception, which will get printed
495 : * when checkExceptionAndStopSolve() is called
496 : */
497 : virtual void setException(const std::string & message);
498 :
499 : /**
500 : * Whether or not an exception has occurred.
501 : */
502 536590674 : virtual bool hasException() { return _has_exception; }
503 :
504 : /**
505 : * Check to see if an exception has occurred on any processor and, if possible,
506 : * force the solve to fail, which will result in the time step being cut.
507 : *
508 : * Notes:
509 : * * The exception have be registered by calling setException() prior to calling this.
510 : * * This is collective on MPI, and must be called simultaneously by all processors!
511 : * * If called when the solve can be interruped, it will do so and also throw a
512 : * MooseException, which must be handled.
513 : * * If called at a stage in the execution when the solve cannot be interupted (i.e.,
514 : * there is no solve active), it will generate an error and terminate the application.
515 : * * DO NOT CALL THIS IN A THREADED REGION! This is meant to be called just after a
516 : * threaded section.
517 : *
518 : * @param print_message whether to print a message with exception information
519 : */
520 : virtual void checkExceptionAndStopSolve(bool print_message = true);
521 :
522 : virtual bool solverSystemConverged(const unsigned int solver_sys_num) override;
523 : virtual unsigned int nNonlinearIterations(const unsigned int nl_sys_num) const override;
524 : virtual unsigned int nLinearIterations(const unsigned int nl_sys_num) const override;
525 : virtual Real finalNonlinearResidual(const unsigned int nl_sys_num) const override;
526 : virtual bool computingPreSMOResidual(const unsigned int nl_sys_num) const override;
527 :
528 : /**
529 : * Return solver type as a human readable string
530 : */
531 : virtual std::string solverTypeString(unsigned int solver_sys_num = 0);
532 :
533 : /**
534 : * Returns true if we are in or beyond the initialSetup stage
535 : */
536 77385 : virtual bool startedInitialSetup() { return _started_initial_setup; }
537 :
538 : virtual void onTimestepBegin() override;
539 : virtual void onTimestepEnd() override;
540 :
541 10068460 : virtual Real & time() const { return _time; }
542 1028579 : virtual Real & timeOld() const { return _time_old; }
543 1530101 : virtual int & timeStep() const { return _t_step; }
544 13761616 : virtual Real & dt() const { return _dt; }
545 1038189 : virtual Real & dtOld() const { return _dt_old; }
546 : /**
547 : * Returns the time associated with the requested \p state
548 : */
549 : Real getTimeFromStateArg(const Moose::StateArg & state) const;
550 :
551 31987 : virtual void transient(bool trans) { _transient = trans; }
552 2493824391 : virtual bool isTransient() const override { return _transient; }
553 :
554 : virtual void addTimeIntegrator(const std::string & type,
555 : const std::string & name,
556 : InputParameters & parameters);
557 : virtual void
558 : addPredictor(const std::string & type, const std::string & name, InputParameters & parameters);
559 :
560 : virtual void copySolutionsBackwards();
561 :
562 : /**
563 : * Advance all of the state holding vectors / datastructures so that we can move to the next
564 : * timestep.
565 : */
566 : virtual void advanceState();
567 :
568 : virtual void restoreSolutions();
569 :
570 : /**
571 : * Allocate vectors and save old solutions into them.
572 : */
573 : virtual void saveOldSolutions();
574 :
575 : /**
576 : * Restore old solutions from the backup vectors and deallocate them.
577 : */
578 : virtual void restoreOldSolutions();
579 :
580 : /**
581 : * Declare that we need up to old (1) or older (2) solution states for a given type of iteration
582 : * @param oldest_needed oldest solution state needed
583 : * @param iteration_type the type of iteration for which old/older states are needed
584 : */
585 : void needSolutionState(unsigned int oldest_needed, Moose::SolutionIterationType iteration_type);
586 :
587 : /**
588 : * Output the current step.
589 : * Will ensure that everything is in the proper state to be outputted.
590 : * Then tell the OutputWarehouse to do its thing
591 : * @param type The type execution flag (see Moose.h)
592 : */
593 : virtual void outputStep(ExecFlagType type);
594 :
595 : /**
596 : * Method called at the end of the simulation.
597 : */
598 : virtual void postExecute();
599 :
600 : ///@{
601 : /**
602 : * Ability to enable/disable all output calls
603 : *
604 : * This is needed by Multiapps and applications to disable output for cases when
605 : * executioners call other executions and when Multiapps are sub cycling.
606 : */
607 : void allowOutput(bool state);
608 : template <typename T>
609 : void allowOutput(bool state);
610 : ///@}
611 :
612 : /**
613 : * Indicates that the next call to outputStep should be forced
614 : *
615 : * This is needed by the MultiApp system, if forceOutput is called the next call to outputStep,
616 : * regardless of the type supplied to the call, will be executed with EXEC_FORCED.
617 : *
618 : * Forced output will NOT override the allowOutput flag.
619 : */
620 : void forceOutput();
621 :
622 : /**
623 : * Reinitialize PETSc output for proper linear/nonlinear iteration display. This also may be used
624 : * for some PETSc-related solver settings
625 : */
626 : virtual void initPetscOutputAndSomeSolverSettings();
627 :
628 : /**
629 : * Retrieve a writable reference the PETSc options (used by PetscSupport)
630 : */
631 214075 : Moose::PetscSupport::PetscOptions & getPetscOptions() { return _petsc_options; }
632 :
633 : /**
634 : * Output information about the object just added to the problem
635 : */
636 : void logAdd(const std::string & system,
637 : const std::string & name,
638 : const std::string & type,
639 : const InputParameters & params) const;
640 :
641 : // Function /////
642 : virtual void
643 : addFunction(const std::string & type, const std::string & name, InputParameters & parameters);
644 : virtual bool hasFunction(const std::string & name, const THREAD_ID tid = 0);
645 : virtual Function & getFunction(const std::string & name, const THREAD_ID tid = 0);
646 :
647 : /// Add a MeshDivision
648 : virtual void
649 : addMeshDivision(const std::string & type, const std::string & name, InputParameters & params);
650 : /// Get a MeshDivision
651 : MeshDivision & getMeshDivision(const std::string & name, const THREAD_ID tid = 0) const;
652 :
653 : /// Adds a Convergence object
654 : virtual void
655 : addConvergence(const std::string & type, const std::string & name, InputParameters & parameters);
656 : /// Gets a Convergence object
657 : virtual Convergence & getConvergence(const std::string & name, const THREAD_ID tid = 0) const;
658 : /// Gets the Convergence objects
659 : virtual const std::vector<std::shared_ptr<Convergence>> &
660 : getConvergenceObjects(const THREAD_ID tid = 0) const;
661 : /// Returns true if the problem has a Convergence object of the given name
662 : virtual bool hasConvergence(const std::string & name, const THREAD_ID tid = 0) const;
663 : /// Returns true if the problem needs to add the default nonlinear convergence
664 64020 : bool needToAddDefaultNonlinearConvergence() const
665 : {
666 64020 : return _need_to_add_default_nonlinear_convergence;
667 : }
668 : /// Returns true if the problem needs to add the default fixed point convergence
669 64008 : bool needToAddDefaultMultiAppFixedPointConvergence() const
670 : {
671 64008 : return _need_to_add_default_multiapp_fixed_point_convergence;
672 : }
673 : /// Returns true if the problem needs to add the default steady-state detection convergence
674 63996 : bool needToAddDefaultSteadyStateConvergence() const
675 : {
676 63996 : return _need_to_add_default_steady_state_convergence;
677 : }
678 : /// Sets _need_to_add_default_nonlinear_convergence to true
679 63403 : void setNeedToAddDefaultNonlinearConvergence()
680 : {
681 63403 : _need_to_add_default_nonlinear_convergence = true;
682 63403 : }
683 : /// Sets _need_to_add_default_multiapp_fixed_point_convergence to true
684 64010 : void setNeedToAddDefaultMultiAppFixedPointConvergence()
685 : {
686 64010 : _need_to_add_default_multiapp_fixed_point_convergence = true;
687 64010 : }
688 : /// Sets _need_to_add_default_steady_state_convergence to true
689 31829 : void setNeedToAddDefaultSteadyStateConvergence()
690 : {
691 31829 : _need_to_add_default_steady_state_convergence = true;
692 31829 : }
693 : /// Returns true if the problem has set the fixed point convergence name
694 63996 : bool hasSetMultiAppFixedPointConvergenceName() const
695 : {
696 63996 : return _multiapp_fixed_point_convergence_name.has_value();
697 : }
698 : /// Returns true if the problem has set the steady-state detection convergence name
699 : bool hasSetSteadyStateConvergenceName() const
700 : {
701 : return _steady_state_convergence_name.has_value();
702 : }
703 : /**
704 : * Adds the default nonlinear Convergence associated with the problem
705 : *
706 : * This is called if the user does not supply 'nonlinear_convergence'.
707 : *
708 : * @param[in] params Parameters to apply to Convergence parameters
709 : */
710 : virtual void addDefaultNonlinearConvergence(const InputParameters & params);
711 : /**
712 : * Returns true if an error will result if the user supplies 'nonlinear_convergence'
713 : *
714 : * Some problems are strongly tied to their convergence, and it does not make
715 : * sense to use any convergence other than their default and additionally
716 : * would be error-prone.
717 : */
718 344 : virtual bool onlyAllowDefaultNonlinearConvergence() const { return false; }
719 : /**
720 : * Adds the default fixed point Convergence associated with the problem
721 : *
722 : * This is called if the user does not supply 'multiapp_fixed_point_convergence'.
723 : *
724 : * @param[in] params Parameters to apply to Convergence parameters
725 : */
726 : void addDefaultMultiAppFixedPointConvergence(const InputParameters & params);
727 : /**
728 : * Adds the default steady-state detection Convergence
729 : *
730 : * This is called if the user does not supply 'steady_state_convergence'.
731 : *
732 : * @param[in] params Parameters to apply to Convergence parameters
733 : */
734 : void addDefaultSteadyStateConvergence(const InputParameters & params);
735 :
736 : /**
737 : * add a MOOSE line search
738 : */
739 0 : virtual void addLineSearch(const InputParameters & /*parameters*/)
740 : {
741 0 : mooseError("Line search not implemented for this problem type yet.");
742 : }
743 :
744 : /**
745 : * execute MOOSE line search
746 : */
747 : virtual void lineSearch();
748 :
749 : /**
750 : * getter for the MOOSE line search
751 : */
752 0 : LineSearch * getLineSearch() override { return _line_search.get(); }
753 :
754 : /**
755 : * The following functions will enable MOOSE to have the capability to import distributions
756 : */
757 : virtual void
758 : addDistribution(const std::string & type, const std::string & name, InputParameters & parameters);
759 : virtual Distribution & getDistribution(const std::string & name);
760 :
761 : /**
762 : * The following functions will enable MOOSE to have the capability to import Samplers
763 : */
764 : virtual void
765 : addSampler(const std::string & type, const std::string & name, InputParameters & parameters);
766 : virtual Sampler & getSampler(const std::string & name, const THREAD_ID tid = 0);
767 :
768 : // NL /////
769 : NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num);
770 : const NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num) const;
771 : void setCurrentNonlinearSystem(const unsigned int nl_sys_num);
772 : NonlinearSystemBase & currentNonlinearSystem();
773 : const NonlinearSystemBase & currentNonlinearSystem() const;
774 :
775 : virtual const SystemBase & systemBaseNonlinear(const unsigned int sys_num) const override;
776 : virtual SystemBase & systemBaseNonlinear(const unsigned int sys_num) override;
777 :
778 : virtual const SystemBase & systemBaseSolver(const unsigned int sys_num) const override;
779 : virtual SystemBase & systemBaseSolver(const unsigned int sys_num) override;
780 :
781 : virtual const SystemBase & systemBaseAuxiliary() const override;
782 : virtual SystemBase & systemBaseAuxiliary() override;
783 :
784 : virtual NonlinearSystem & getNonlinearSystem(const unsigned int sys_num);
785 :
786 : #ifdef MOOSE_KOKKOS_ENABLED
787 : /**
788 : * Get all Kokkos systems that are associated with MOOSE nonlinear and auxiliary systems
789 : * @returns The array of Kokkos systems
790 : */
791 : ///{@
792 44541 : Moose::Kokkos::Array<Moose::Kokkos::System> & getKokkosSystems() { return _kokkos_systems; }
793 : const Moose::Kokkos::Array<Moose::Kokkos::System> & getKokkosSystems() const
794 : {
795 : return _kokkos_systems;
796 : }
797 : ///@}
798 : /**
799 : * Get the Kokkos system of a specified number that is associated with MOOSE nonlinear and
800 : * auxiliary systems
801 : * @param sys_num The system number
802 : * @returns The Kokkos system
803 : */
804 : ///{@
805 : Moose::Kokkos::System & getKokkosSystem(const unsigned int sys_num);
806 : const Moose::Kokkos::System & getKokkosSystem(const unsigned int sys_num) const;
807 : ///@}
808 : #endif
809 :
810 : /**
811 : * Get constant reference to a system in this problem
812 : * @param sys_num The number of the system
813 : */
814 : virtual const SystemBase & getSystemBase(const unsigned int sys_num) const;
815 :
816 : /**
817 : * Get non-constant reference to a system in this problem
818 : * @param sys_num The number of the system
819 : */
820 : virtual SystemBase & getSystemBase(const unsigned int sys_num);
821 :
822 : /**
823 : * Get non-constant reference to a system in this problem
824 : * @param sys_name The name of the system
825 : */
826 : SystemBase & getSystemBase(const std::string & sys_name);
827 :
828 : /**
829 : * Get non-constant reference to a linear system
830 : * @param sys_num The number of the linear system
831 : */
832 : LinearSystem & getLinearSystem(unsigned int sys_num);
833 :
834 : /**
835 : * Get a constant reference to a linear system
836 : * @param sys_num The number of the linear system
837 : */
838 : const LinearSystem & getLinearSystem(unsigned int sys_num) const;
839 :
840 : /**
841 : * Get non-constant reference to a solver system
842 : * @param sys_num The number of the solver system
843 : */
844 : SolverSystem & getSolverSystem(unsigned int sys_num);
845 :
846 : /**
847 : * Get a constant reference to a solver system
848 : * @param sys_num The number of the solver system
849 : */
850 : const SolverSystem & getSolverSystem(unsigned int sys_num) const;
851 :
852 : /**
853 : * Set the current linear system pointer
854 : * @param sys_num The number of linear system
855 : */
856 : void setCurrentLinearSystem(unsigned int sys_num);
857 :
858 : /// Get a non-constant reference to the current linear system
859 : LinearSystem & currentLinearSystem();
860 : /// Get a constant reference to the current linear system
861 : const LinearSystem & currentLinearSystem() const;
862 :
863 : /**
864 : * Get a constant base class reference to a linear system
865 : * @param sys_num The number of the linear system
866 : */
867 : virtual const SystemBase & systemBaseLinear(unsigned int sys_num) const override;
868 :
869 : /**
870 : * Get a non-constant base class reference to a linear system
871 : * @param sys_num The number of the linear system
872 : */
873 : virtual SystemBase & systemBaseLinear(unsigned int sys_num) override;
874 :
875 : /**
876 : * Canonical method for adding a non-linear variable
877 : * @param var_type the type of the variable, e.g. MooseVariableScalar
878 : * @param var_name the variable name, e.g. 'u'
879 : * @param params the InputParameters from which to construct the variable
880 : */
881 : virtual void
882 : addVariable(const std::string & var_type, const std::string & var_name, InputParameters & params);
883 :
884 : virtual void addKernel(const std::string & kernel_name,
885 : const std::string & name,
886 : InputParameters & parameters);
887 : virtual void addHDGKernel(const std::string & kernel_name,
888 : const std::string & name,
889 : InputParameters & parameters);
890 : virtual void addNodalKernel(const std::string & kernel_name,
891 : const std::string & name,
892 : InputParameters & parameters);
893 : virtual void addScalarKernel(const std::string & kernel_name,
894 : const std::string & name,
895 : InputParameters & parameters);
896 : virtual void addBoundaryCondition(const std::string & bc_name,
897 : const std::string & name,
898 : InputParameters & parameters);
899 :
900 : #ifdef MOOSE_KOKKOS_ENABLED
901 : virtual void addKokkosKernel(const std::string & kernel_name,
902 : const std::string & name,
903 : InputParameters & parameters);
904 : virtual void addKokkosNodalKernel(const std::string & kernel_name,
905 : const std::string & name,
906 : InputParameters & parameters);
907 : virtual void addKokkosBoundaryCondition(const std::string & bc_name,
908 : const std::string & name,
909 : InputParameters & parameters);
910 : #endif
911 :
912 : virtual void
913 : addConstraint(const std::string & c_name, const std::string & name, InputParameters & parameters);
914 :
915 1788330 : virtual void setInputParametersFEProblem(InputParameters & parameters)
916 : {
917 3576660 : parameters.set<FEProblemBase *>("_fe_problem_base") = this;
918 1788330 : }
919 :
920 : // Aux /////
921 :
922 : /**
923 : * Canonical method for adding an auxiliary variable
924 : * @param var_type the type of the variable, e.g. MooseVariableScalar
925 : * @param var_name the variable name, e.g. 'u'
926 : * @param params the InputParameters from which to construct the variable
927 : */
928 : virtual void addAuxVariable(const std::string & var_type,
929 : const std::string & var_name,
930 : InputParameters & params);
931 :
932 : virtual void addAuxVariable(const std::string & var_name,
933 : const libMesh::FEType & type,
934 : const std::set<SubdomainID> * const active_subdomains = NULL);
935 : virtual void addAuxArrayVariable(const std::string & var_name,
936 : const libMesh::FEType & type,
937 : unsigned int components,
938 : const std::set<SubdomainID> * const active_subdomains = NULL);
939 : virtual void addAuxScalarVariable(const std::string & var_name,
940 : libMesh::Order order,
941 : Real scale_factor = 1.,
942 : const std::set<SubdomainID> * const active_subdomains = NULL);
943 : virtual void addAuxKernel(const std::string & kernel_name,
944 : const std::string & name,
945 : InputParameters & parameters);
946 : virtual void addAuxScalarKernel(const std::string & kernel_name,
947 : const std::string & name,
948 : InputParameters & parameters);
949 :
950 : #ifdef MOOSE_KOKKOS_ENABLED
951 : virtual void addKokkosAuxKernel(const std::string & kernel_name,
952 : const std::string & name,
953 : InputParameters & parameters);
954 : #endif
955 :
956 5272544 : AuxiliarySystem & getAuxiliarySystem() { return *_aux; }
957 :
958 : // Dirac /////
959 : virtual void addDiracKernel(const std::string & kernel_name,
960 : const std::string & name,
961 : InputParameters & parameters);
962 :
963 : // DG /////
964 : virtual void addDGKernel(const std::string & kernel_name,
965 : const std::string & name,
966 : InputParameters & parameters);
967 : // FV /////
968 : virtual void addFVKernel(const std::string & kernel_name,
969 : const std::string & name,
970 : InputParameters & parameters);
971 :
972 : virtual void addLinearFVKernel(const std::string & kernel_name,
973 : const std::string & name,
974 : InputParameters & parameters);
975 : virtual void
976 : addFVBC(const std::string & fv_bc_name, const std::string & name, InputParameters & parameters);
977 : virtual void addLinearFVBC(const std::string & fv_bc_name,
978 : const std::string & name,
979 : InputParameters & parameters);
980 :
981 : virtual void addFVInterfaceKernel(const std::string & fv_ik_name,
982 : const std::string & name,
983 : InputParameters & parameters);
984 :
985 : // Interface /////
986 : virtual void addInterfaceKernel(const std::string & kernel_name,
987 : const std::string & name,
988 : InputParameters & parameters);
989 :
990 : // IC /////
991 : virtual void addInitialCondition(const std::string & ic_name,
992 : const std::string & name,
993 : InputParameters & parameters);
994 : /**
995 : * Add an initial condition for a finite volume variables
996 : * @param ic_name The name of the boundary condition object
997 : * @param name The user-defined name from the input file
998 : * @param parameters The input parameters for construction
999 : */
1000 : virtual void addFVInitialCondition(const std::string & ic_name,
1001 : const std::string & name,
1002 : InputParameters & parameters);
1003 :
1004 : void projectSolution();
1005 :
1006 : /**
1007 : * Retrieves the current initial condition state.
1008 : * @return current initial condition state
1009 : */
1010 : unsigned short getCurrentICState();
1011 :
1012 : /**
1013 : * Project initial conditions for custom \p elem_range and \p bnd_node_range
1014 : * This is needed when elements/boundary nodes are added to a specific subdomain
1015 : * at an intermediate step
1016 : * @param elem_range Element range to project on
1017 : * @param bnd_node_range Boundary node range to project on
1018 : * @param target_vars Set of variable names to project ICs
1019 : */
1020 : void projectInitialConditionOnCustomRange(
1021 : libMesh::ConstElemRange & elem_range,
1022 : ConstBndNodeRange & bnd_node_range,
1023 : const std::optional<std::set<VariableName>> & target_vars = std::nullopt);
1024 :
1025 : /**
1026 : * Project a function onto a range of elements for a given variable
1027 : *
1028 : * @warning The current implementation is not ideal. The projection takes place on all local
1029 : * active elements, ignoring the specified \p elem_range. After the projection, dof values on the
1030 : * specified \p elem_range are copied over to the current solution vector. This should be fixed
1031 : * once the project_vector or project_solution API is modified to take a custom element range.
1032 : *
1033 : * \param elem_range Element range to project on
1034 : * \param func Function to project
1035 : * \param func_grad Gradient of the function
1036 : * \param params Parameters to pass to the function
1037 : * \param target_var variable name to project
1038 : */
1039 : void projectFunctionOnCustomRange(ConstElemRange & elem_range,
1040 : Number (*func)(const Point &,
1041 : const libMesh::Parameters &,
1042 : const std::string &,
1043 : const std::string &),
1044 : Gradient (*func_grad)(const Point &,
1045 : const libMesh::Parameters &,
1046 : const std::string &,
1047 : const std::string &),
1048 : const libMesh::Parameters & params,
1049 : const VariableName & target_var);
1050 :
1051 : // Materials
1052 : virtual void addMaterial(const std::string & material_name,
1053 : const std::string & name,
1054 : InputParameters & parameters);
1055 : virtual void addMaterialHelper(std::vector<MaterialWarehouse *> warehouse,
1056 : const std::string & material_name,
1057 : const std::string & name,
1058 : InputParameters & parameters);
1059 : virtual void addInterfaceMaterial(const std::string & material_name,
1060 : const std::string & name,
1061 : InputParameters & parameters);
1062 : virtual void addFunctorMaterial(const std::string & functor_material_name,
1063 : const std::string & name,
1064 : InputParameters & parameters);
1065 :
1066 : #ifdef MOOSE_KOKKOS_ENABLED
1067 : virtual void addKokkosMaterial(const std::string & material_name,
1068 : const std::string & name,
1069 : InputParameters & parameters);
1070 : #endif
1071 :
1072 : /**
1073 : * Add the MooseVariables and the material properties that the current materials depend on to the
1074 : * dependency list.
1075 : * @param consumer_needed_mat_props The material properties needed by consumer objects (other than
1076 : * the materials themselves)
1077 : * @param blk_id The subdomain ID for which we are preparing our list of needed vars and props
1078 : * @param tid The thread ID we are preparing the requirements for
1079 : *
1080 : * This MUST be done after the moose variable dependency list has been set for all the other
1081 : * objects using the \p setActiveElementalMooseVariables API!
1082 : */
1083 : void prepareMaterials(const std::unordered_set<unsigned int> & consumer_needed_mat_props,
1084 : const SubdomainID blk_id,
1085 : const THREAD_ID tid);
1086 :
1087 : void reinitMaterials(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful = true);
1088 :
1089 : /**
1090 : * reinit materials on element faces
1091 : * @param blk_id The subdomain on which the element owning the face lives
1092 : * @param tid The thread id
1093 : * @param swap_stateful Whether to swap stateful material properties between \p MaterialData and
1094 : * \p MaterialPropertyStorage
1095 : * @param reinit_mats specific list of materials to reinit. Used notably in the context of mortar
1096 : * with stateful elements
1097 : */
1098 : void reinitMaterialsFace(SubdomainID blk_id,
1099 : const THREAD_ID tid,
1100 : bool swap_stateful = true,
1101 : const std::deque<MaterialBase *> * reinit_mats = nullptr);
1102 :
1103 : /**
1104 : * reinit materials on element faces on a boundary (internal or external)
1105 : * This specific routine helps us not reinit when don't need to
1106 : * @param boundary_id The boundary on which the face belongs
1107 : * @param blk_id The block id to which the element (who owns the face) belong
1108 : * @param tid The thread id
1109 : * @param swap_stateful Whether to swap stateful material properties between \p MaterialData and
1110 : * \p MaterialPropertyStorage
1111 : * @param reinit_mats specific list of materials to reinit. Used notably in the context of mortar
1112 : * with stateful elements
1113 : */
1114 : void
1115 : reinitMaterialsFaceOnBoundary(const BoundaryID boundary_id,
1116 : const SubdomainID blk_id,
1117 : const THREAD_ID tid,
1118 : const bool swap_stateful = true,
1119 : const std::deque<MaterialBase *> * const reinit_mats = nullptr);
1120 :
1121 : /**
1122 : * reinit materials on neighbor element (usually faces) on a boundary (internal or external)
1123 : * This specific routine helps us not reinit when don't need to
1124 : * @param boundary_id The boundary on which the face belongs
1125 : * @param blk_id The block id to which the element (who owns the face) belong
1126 : * @param tid The thread id
1127 : * @param swap_stateful Whether to swap stateful material properties between \p MaterialData and
1128 : * \p MaterialPropertyStorage
1129 : * @param reinit_mats specific list of materials to reinit. Used notably in the context of mortar
1130 : * with stateful elements
1131 : */
1132 : void
1133 : reinitMaterialsNeighborOnBoundary(const BoundaryID boundary_id,
1134 : const SubdomainID blk_id,
1135 : const THREAD_ID tid,
1136 : const bool swap_stateful = true,
1137 : const std::deque<MaterialBase *> * const reinit_mats = nullptr);
1138 :
1139 : /**
1140 : * reinit materials on the neighboring element face
1141 : * @param blk_id The subdomain on which the neighbor element lives
1142 : * @param tid The thread id
1143 : * @param swap_stateful Whether to swap stateful material properties between \p MaterialData and
1144 : * \p MaterialPropertyStorage
1145 : * @param reinit_mats specific list of materials to reinit. Used notably in the context of mortar
1146 : * with stateful elements
1147 : */
1148 : void reinitMaterialsNeighbor(SubdomainID blk_id,
1149 : const THREAD_ID tid,
1150 : bool swap_stateful = true,
1151 : const std::deque<MaterialBase *> * reinit_mats = nullptr);
1152 :
1153 : /**
1154 : * reinit materials on a boundary
1155 : * @param boundary_id The boundary on which to reinit corresponding materials
1156 : * @param tid The thread id
1157 : * @param swap_stateful Whether to swap stateful material properties between \p MaterialData and
1158 : * \p MaterialPropertyStorage
1159 : * @param execute_stateful Whether to execute material objects that have stateful properties.
1160 : * This should be \p false when for example executing material objects for mortar contexts in
1161 : * which stateful properties don't make sense
1162 : * @param reinit_mats specific list of materials to reinit. Used notably in the context of mortar
1163 : * with stateful elements
1164 : */
1165 : void reinitMaterialsBoundary(BoundaryID boundary_id,
1166 : const THREAD_ID tid,
1167 : bool swap_stateful = true,
1168 : const std::deque<MaterialBase *> * reinit_mats = nullptr);
1169 :
1170 : void
1171 : reinitMaterialsInterface(BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful = true);
1172 :
1173 : #ifdef MOOSE_KOKKOS_ENABLED
1174 : void prepareKokkosMaterials(const std::unordered_set<unsigned int> & consumer_needed_mat_props);
1175 : void reinitKokkosMaterials();
1176 : #endif
1177 :
1178 : /*
1179 : * Swap back underlying data storing stateful material properties
1180 : */
1181 : virtual void swapBackMaterials(const THREAD_ID tid);
1182 : virtual void swapBackMaterialsFace(const THREAD_ID tid);
1183 : virtual void swapBackMaterialsNeighbor(const THREAD_ID tid);
1184 :
1185 : /**
1186 : * Record and set the material properties required by the current computing thread.
1187 : * @param mat_prop_ids The set of material properties required by the current computing thread.
1188 : *
1189 : * @param tid The thread id
1190 : */
1191 : void setActiveMaterialProperties(const std::unordered_set<unsigned int> & mat_prop_ids,
1192 : const THREAD_ID tid);
1193 :
1194 : /**
1195 : * Method to check whether or not a list of active material roperties has been set. This method
1196 : * is called by reinitMaterials to determine whether Material computeProperties methods need to be
1197 : * called. If the return is False, this check prevents unnecessary material property computation
1198 : * @param tid The thread id
1199 : *
1200 : * @return True if there has been a list of active material properties set, False otherwise
1201 : */
1202 : bool hasActiveMaterialProperties(const THREAD_ID tid) const;
1203 :
1204 : /**
1205 : * Clear the active material properties. Should be called at the end of every computing thread
1206 : *
1207 : * @param tid The thread id
1208 : */
1209 : void clearActiveMaterialProperties(const THREAD_ID tid);
1210 :
1211 : /**
1212 : * Method for creating and adding an object to the warehouse.
1213 : *
1214 : * @tparam T The base object type (registered in the Factory)
1215 : * @param type String type of the object (registered in the Factory)
1216 : * @param name Name for the object to be created
1217 : * @param parameters InputParameters for the object
1218 : * @param threaded Whether or not to create n_threads copies of the object
1219 : * @param var_param_name The name of the parameter on the object which holds the primary variable.
1220 : * @return A vector of shared_ptrs to the added objects
1221 : */
1222 : template <typename T>
1223 : std::vector<std::shared_ptr<T>> addObject(const std::string & type,
1224 : const std::string & name,
1225 : InputParameters & parameters,
1226 : const bool threaded = true,
1227 : const std::string & var_param_name = "variable");
1228 :
1229 : // Postprocessors /////
1230 : virtual void addPostprocessor(const std::string & pp_name,
1231 : const std::string & name,
1232 : InputParameters & parameters);
1233 :
1234 : // VectorPostprocessors /////
1235 : virtual void addVectorPostprocessor(const std::string & pp_name,
1236 : const std::string & name,
1237 : InputParameters & parameters);
1238 :
1239 : /**
1240 : * Add a Reporter object to the simulation.
1241 : * @param type C++ object type to construct
1242 : * @param name A uniquely identifying object name
1243 : * @param parameters Complete parameters for the object to be created.
1244 : *
1245 : * For an example use, refer to AddReporterAction.C/h
1246 : */
1247 : virtual void
1248 : addReporter(const std::string & type, const std::string & name, InputParameters & parameters);
1249 :
1250 : /**
1251 : * Provides const access the ReporterData object.
1252 : *
1253 : * NOTE: There is a private non-const version of this function that uses a key object only
1254 : * constructable by the correct interfaces. This was done by design to encourage the use of
1255 : * the Reporter and ReporterInterface classes.
1256 : */
1257 793643 : const ReporterData & getReporterData() const { return _reporter_data; }
1258 :
1259 : /**
1260 : * Provides non-const access the ReporterData object that is used to store reporter values.
1261 : *
1262 : * see ReporterData.h
1263 : */
1264 154780 : ReporterData & getReporterData(ReporterData::WriteKey /*key*/) { return _reporter_data; }
1265 :
1266 : // UserObjects /////
1267 : virtual std::vector<std::shared_ptr<UserObject>> addUserObject(
1268 : const std::string & user_object_name, const std::string & name, InputParameters & parameters);
1269 :
1270 : // TODO: delete this function after apps have been updated to not call it
1271 : const ExecuteMooseObjectWarehouse<UserObject> & getUserObjects() const
1272 : {
1273 : mooseDeprecated(
1274 : "This function is deprecated, use theWarehouse().query() to construct a query instead");
1275 : return _all_user_objects;
1276 : }
1277 :
1278 : /**
1279 : * Get the user object by its name
1280 : * @param name The name of the user object being retrieved
1281 : * @return Const reference to the user object
1282 : */
1283 : template <class T>
1284 42266 : T & getUserObject(const std::string & name, unsigned int tid = 0) const
1285 : {
1286 42266 : std::vector<T *> objs;
1287 42266 : theWarehouse()
1288 : .query()
1289 84532 : .condition<AttribSystem>("UserObject")
1290 42266 : .condition<AttribThread>(tid)
1291 42266 : .condition<AttribName>(name)
1292 42266 : .queryInto(objs);
1293 42266 : if (objs.empty())
1294 0 : mooseError("Unable to find user object with name '" + name + "'");
1295 84532 : return *(objs[0]);
1296 42266 : }
1297 : /**
1298 : * Get the user object by its name
1299 : * @param name The name of the user object being retrieved
1300 : * @param tid The thread of the user object (defaults to 0)
1301 : * @return Const reference to the user object
1302 : */
1303 : const UserObject & getUserObjectBase(const std::string & name, const THREAD_ID tid = 0) const;
1304 :
1305 : /**
1306 : * Get the Positions object by its name
1307 : * @param name The name of the Positions object being retrieved
1308 : * @return Const reference to the Positions object
1309 : */
1310 : const Positions & getPositionsObject(const std::string & name) const;
1311 :
1312 : /**
1313 : * Check if there if a user object of given name
1314 : * @param name The name of the user object being checked for
1315 : * @return true if the user object exists, false otherwise
1316 : */
1317 : bool hasUserObject(const std::string & name) const;
1318 :
1319 : /**
1320 : * Whether or not a Postprocessor value exists by a given name.
1321 : * @param name The name of the Postprocessor
1322 : * @return True if a Postprocessor value exists
1323 : *
1324 : * Note: You should prioritize the use of PostprocessorInterface::hasPostprocessor
1325 : * and PostprocessorInterface::hasPostprocessorByName over this method when possible.
1326 : */
1327 : bool hasPostprocessorValueByName(const PostprocessorName & name) const;
1328 :
1329 : /**
1330 : * Get a read-only reference to the value associated with a Postprocessor that exists.
1331 : * @param name The name of the post-processor
1332 : * @param t_index Flag for getting current (0), old (1), or older (2) values
1333 : * @return The reference to the value at the given time index
1334 : *
1335 : * Note: This method is only for retrieving values that already exist, the Postprocessor and
1336 : * PostprocessorInterface objects should be used rather than this method for creating
1337 : * and getting values within objects.
1338 : */
1339 : const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName & name,
1340 : std::size_t t_index = 0) const;
1341 :
1342 : /**
1343 : * Set the value of a PostprocessorValue.
1344 : * @param name The name of the post-processor
1345 : * @param t_index Flag for getting current (0), old (1), or older (2) values
1346 : * @return The reference to the value at the given time index
1347 : *
1348 : * Note: This method is only for setting values that already exist, the Postprocessor and
1349 : * PostprocessorInterface objects should be used rather than this method for creating
1350 : * and getting values within objects.
1351 : *
1352 : * WARNING!
1353 : * This method should be used with caution. It exists to allow Transfers and other
1354 : * similar objects to modify Postprocessor values. It is not intended for general use.
1355 : */
1356 : void setPostprocessorValueByName(const PostprocessorName & name,
1357 : const PostprocessorValue & value,
1358 : std::size_t t_index = 0);
1359 :
1360 : /**
1361 : * Deprecated. Use hasPostprocessorValueByName
1362 : */
1363 : bool hasPostprocessor(const std::string & name) const;
1364 :
1365 : /**
1366 : * Get a read-only reference to the vector value associated with the VectorPostprocessor.
1367 : * @param object_name The name of the VPP object.
1368 : * @param vector_name The namve of the decalred vector within the object.
1369 : * @return Referent to the vector of data.
1370 : *
1371 : * Note: This method is only for retrieving values that already exist, the VectorPostprocessor and
1372 : * VectorPostprocessorInterface objects should be used rather than this method for creating
1373 : * and getting values within objects.
1374 : */
1375 : const VectorPostprocessorValue &
1376 : getVectorPostprocessorValueByName(const std::string & object_name,
1377 : const std::string & vector_name,
1378 : std::size_t t_index = 0) const;
1379 :
1380 : /**
1381 : * Set the value of a VectorPostprocessor vector
1382 : * @param object_name The name of the VPP object
1383 : * @param vector_name The name of the declared vector
1384 : * @param value The data to apply to the vector
1385 : * @param t_index Flag for getting current (0), old (1), or older (2) values
1386 : */
1387 : void setVectorPostprocessorValueByName(const std::string & object_name,
1388 : const std::string & vector_name,
1389 : const VectorPostprocessorValue & value,
1390 : std::size_t t_index = 0);
1391 :
1392 : /**
1393 : * Return the VPP object given the name.
1394 : * @param object_name The name of the VPP object
1395 : * @return Desired VPP object
1396 : *
1397 : * This is used by various output objects as well as the scatter value handling.
1398 : * @see CSV.C, XMLOutput.C, VectorPostprocessorInterface.C
1399 : */
1400 : const VectorPostprocessor & getVectorPostprocessorObjectByName(const std::string & object_name,
1401 : const THREAD_ID tid = 0) const;
1402 :
1403 : ///@{
1404 : /**
1405 : * Returns whether or not the current simulation has any multiapps
1406 : */
1407 863 : bool hasMultiApps() const { return _multi_apps.hasActiveObjects(); }
1408 : bool hasMultiApps(ExecFlagType type) const;
1409 : bool hasMultiApp(const std::string & name) const;
1410 : ///@}
1411 :
1412 : // Dampers /////
1413 : virtual void addDamper(const std::string & damper_name,
1414 : const std::string & name,
1415 : InputParameters & parameters);
1416 : void setupDampers();
1417 :
1418 : /**
1419 : * Whether or not this system has dampers.
1420 : */
1421 377979 : bool hasDampers() { return _has_dampers; }
1422 :
1423 : // Indicators /////
1424 : virtual void addIndicator(const std::string & indicator_name,
1425 : const std::string & name,
1426 : InputParameters & parameters);
1427 :
1428 : // Markers //////
1429 : virtual void addMarker(const std::string & marker_name,
1430 : const std::string & name,
1431 : InputParameters & parameters);
1432 :
1433 : /**
1434 : * Add a MultiApp to the problem.
1435 : */
1436 : virtual void addMultiApp(const std::string & multi_app_name,
1437 : const std::string & name,
1438 : InputParameters & parameters);
1439 :
1440 : /**
1441 : * Get a MultiApp object by name.
1442 : */
1443 : std::shared_ptr<MultiApp> getMultiApp(const std::string & multi_app_name) const;
1444 :
1445 : /**
1446 : * Get Transfers by ExecFlagType and direction
1447 : */
1448 : std::vector<std::shared_ptr<Transfer>> getTransfers(ExecFlagType type,
1449 : Transfer::DIRECTION direction) const;
1450 : std::vector<std::shared_ptr<Transfer>> getTransfers(Transfer::DIRECTION direction) const;
1451 :
1452 : /**
1453 : * Return the complete warehouse for MultiAppTransfer object for the given direction
1454 : */
1455 : const ExecuteMooseObjectWarehouse<Transfer> &
1456 : getMultiAppTransferWarehouse(Transfer::DIRECTION direction) const;
1457 :
1458 : /**
1459 : * Execute MultiAppTransfers associated with execution flag and direction.
1460 : * @param type The execution flag to execute.
1461 : * @param direction The direction (to or from) to transfer.
1462 : */
1463 : void execMultiAppTransfers(ExecFlagType type, Transfer::DIRECTION direction);
1464 :
1465 : /**
1466 : * Execute the MultiApps associated with the ExecFlagType
1467 : */
1468 : bool execMultiApps(ExecFlagType type, bool auto_advance = true);
1469 :
1470 : void finalizeMultiApps();
1471 :
1472 : /**
1473 : * Advance the MultiApps t_step (incrementStepOrReject) associated with the ExecFlagType
1474 : */
1475 : void incrementMultiAppTStep(ExecFlagType type);
1476 :
1477 : /**
1478 : * Deprecated method; use finishMultiAppStep and/or incrementMultiAppTStep depending
1479 : * on your purpose
1480 : */
1481 : void advanceMultiApps(ExecFlagType type)
1482 : {
1483 : mooseDeprecated("Deprecated method; use finishMultiAppStep and/or incrementMultiAppTStep "
1484 : "depending on your purpose");
1485 : finishMultiAppStep(type);
1486 : }
1487 :
1488 : /**
1489 : * Finish the MultiApp time step (endStep, postStep) associated with the ExecFlagType. Optionally
1490 : * recurse through all multi-app levels
1491 : */
1492 : void finishMultiAppStep(ExecFlagType type, bool recurse_through_multiapp_levels = false);
1493 :
1494 : /**
1495 : * Backup the MultiApps associated with the ExecFlagType
1496 : */
1497 : void backupMultiApps(ExecFlagType type);
1498 :
1499 : /**
1500 : * Restore the MultiApps associated with the ExecFlagType
1501 : * @param force Force restoration because something went wrong with the solve
1502 : */
1503 : void restoreMultiApps(ExecFlagType type, bool force = false);
1504 :
1505 : /**
1506 : * Find the smallest timestep over all MultiApps
1507 : */
1508 : Real computeMultiAppsDT(ExecFlagType type);
1509 :
1510 : /**
1511 : * Add a Transfer to the problem.
1512 : */
1513 : virtual void addTransfer(const std::string & transfer_name,
1514 : const std::string & name,
1515 : InputParameters & parameters);
1516 :
1517 : /**
1518 : * Execute the Transfers associated with the ExecFlagType
1519 : *
1520 : * Note: This does _not_ execute MultiApp Transfers!
1521 : * Those are executed automatically when MultiApps are executed.
1522 : */
1523 : void execTransfers(ExecFlagType type);
1524 :
1525 : /**
1526 : * Computes the residual of a nonlinear system using whatever is sitting in the current
1527 : * solution vector then returns the L2 norm.
1528 : */
1529 : Real computeResidualL2Norm(NonlinearSystemBase & sys);
1530 :
1531 : /**
1532 : * Computes the residual of a linear system using whatever is sitting in the current
1533 : * solution vector then returns the L2 norm.
1534 : */
1535 : Real computeResidualL2Norm(LinearSystem & sys);
1536 :
1537 : /**
1538 : * Computes the residual using whatever is sitting in the current solution vector then returns the
1539 : * L2 norm.
1540 : *
1541 : * @return The L2 norm of the residual
1542 : */
1543 : virtual Real computeResidualL2Norm();
1544 :
1545 : /**
1546 : * This function is called by Libmesh to form a residual.
1547 : */
1548 : virtual void computeResidualSys(libMesh::NonlinearImplicitSystem & sys,
1549 : const NumericVector<libMesh::Number> & soln,
1550 : NumericVector<libMesh::Number> & residual);
1551 : /**
1552 : * This function is called by Libmesh to form a residual. This is deprecated.
1553 : * We should remove this as soon as RattleSnake is fixed.
1554 : */
1555 : void computeResidual(libMesh::NonlinearImplicitSystem & sys,
1556 : const NumericVector<libMesh::Number> & soln,
1557 : NumericVector<libMesh::Number> & residual);
1558 :
1559 : /**
1560 : * Form a residual with default tags (nontime, time, residual).
1561 : */
1562 : virtual void computeResidual(const NumericVector<libMesh::Number> & soln,
1563 : NumericVector<libMesh::Number> & residual,
1564 : const unsigned int nl_sys_num);
1565 :
1566 : /**
1567 : * Form a residual and Jacobian with default tags
1568 : */
1569 : void computeResidualAndJacobian(const NumericVector<libMesh::Number> & soln,
1570 : NumericVector<libMesh::Number> & residual,
1571 : libMesh::SparseMatrix<libMesh::Number> & jacobian);
1572 :
1573 : /**
1574 : * Form a residual vector for a given tag
1575 : */
1576 : virtual void computeResidualTag(const NumericVector<libMesh::Number> & soln,
1577 : NumericVector<libMesh::Number> & residual,
1578 : TagID tag);
1579 : /**
1580 : * Form a residual vector for a given tag and "residual" tag
1581 : */
1582 : virtual void computeResidualType(const NumericVector<libMesh::Number> & soln,
1583 : NumericVector<libMesh::Number> & residual,
1584 : TagID tag);
1585 :
1586 : /**
1587 : * Form a residual vector for a set of tags. It should not be called directly
1588 : * by users.
1589 : */
1590 : virtual void computeResidualInternal(const NumericVector<libMesh::Number> & soln,
1591 : NumericVector<libMesh::Number> & residual,
1592 : const std::set<TagID> & tags);
1593 : /**
1594 : * Form multiple residual vectors and each is associated with one tag
1595 : */
1596 : virtual void computeResidualTags(const std::set<TagID> & tags);
1597 :
1598 : /**
1599 : * Form a Jacobian matrix. It is called by Libmesh.
1600 : */
1601 : virtual void computeJacobianSys(libMesh::NonlinearImplicitSystem & sys,
1602 : const NumericVector<libMesh::Number> & soln,
1603 : libMesh::SparseMatrix<libMesh::Number> & jacobian);
1604 : /**
1605 : * Form a Jacobian matrix with the default tag (system).
1606 : */
1607 : virtual void computeJacobian(const NumericVector<libMesh::Number> & soln,
1608 : libMesh::SparseMatrix<libMesh::Number> & jacobian,
1609 : const unsigned int nl_sys_num);
1610 :
1611 : /**
1612 : * Form a Jacobian matrix for a given tag.
1613 : */
1614 : virtual void computeJacobianTag(const NumericVector<libMesh::Number> & soln,
1615 : libMesh::SparseMatrix<libMesh::Number> & jacobian,
1616 : TagID tag);
1617 :
1618 : /**
1619 : * Form a Jacobian matrix for multiple tags. It should not be called directly by users.
1620 : */
1621 : virtual void computeJacobianInternal(const NumericVector<libMesh::Number> & soln,
1622 : libMesh::SparseMatrix<libMesh::Number> & jacobian,
1623 : const std::set<TagID> & tags);
1624 :
1625 : /**
1626 : * Form multiple matrices, and each is associated with a tag.
1627 : */
1628 : virtual void computeJacobianTags(const std::set<TagID> & tags);
1629 :
1630 : /**
1631 : * Computes several Jacobian blocks simultaneously, summing their contributions into smaller
1632 : * preconditioning matrices.
1633 : *
1634 : * Used by Physics-based preconditioning
1635 : *
1636 : * @param blocks The blocks to fill in (JacobianBlock is defined in ComputeJacobianBlocksThread)
1637 : */
1638 : virtual void computeJacobianBlocks(std::vector<JacobianBlock *> & blocks,
1639 : const unsigned int nl_sys_num);
1640 :
1641 : /**
1642 : * Really not a good idea to use this.
1643 : *
1644 : * It computes just one block of the Jacobian into a smaller matrix. Calling this in a loop is
1645 : * EXTREMELY ineffecient!
1646 : * Try to use computeJacobianBlocks() instead!
1647 : *
1648 : * @param jacobian The matrix you want to fill
1649 : * @param precond_system The libMesh::system of the preconditioning system
1650 : * @param ivar the block-row of the Jacobian
1651 : * @param jvar the block-column of the Jacobian
1652 : *
1653 : */
1654 : virtual void computeJacobianBlock(libMesh::SparseMatrix<libMesh::Number> & jacobian,
1655 : libMesh::System & precond_system,
1656 : unsigned int ivar,
1657 : unsigned int jvar);
1658 :
1659 : /**
1660 : * Assemble both the right hand side and the system matrix of a given linear
1661 : * system.
1662 : * @param sys The linear system which should be assembled
1663 : * @param system_matrix The sparse matrix which should hold the system matrix
1664 : * @param rhs The vector which should hold the right hand side
1665 : * @param compute_gradients A flag to disable the computation of new gradients during the
1666 : * assembly, can be used to lag gradients
1667 : */
1668 : virtual void computeLinearSystemSys(libMesh::LinearImplicitSystem & sys,
1669 : libMesh::SparseMatrix<libMesh::Number> & system_matrix,
1670 : NumericVector<libMesh::Number> & rhs,
1671 : const bool compute_gradients = true);
1672 :
1673 : /**
1674 : * Assemble the current linear system given a set of vector and matrix tags.
1675 : *
1676 : * @param soln The solution which should be used for the system assembly
1677 : * @param vector_tags The vector tags for the right hand side
1678 : * @param matrix_tags The matrix tags for the matrix
1679 : * @param compute_gradients A flag to disable the computation of new gradients during the
1680 : * assembly, can be used to lag gradients
1681 : */
1682 : void computeLinearSystemTags(const NumericVector<libMesh::Number> & soln,
1683 : const std::set<TagID> & vector_tags,
1684 : const std::set<TagID> & matrix_tags,
1685 : const bool compute_gradients = true);
1686 :
1687 : virtual Real computeDamping(const NumericVector<libMesh::Number> & soln,
1688 : const NumericVector<libMesh::Number> & update);
1689 :
1690 : /**
1691 : * Check to see whether the problem should update the solution
1692 : * @return true if the problem should update the solution, false otherwise
1693 : */
1694 : virtual bool shouldUpdateSolution();
1695 :
1696 : /**
1697 : * Update the solution
1698 : * @param vec_solution Local solution vector that gets modified by this method
1699 : * @param ghosted_solution Ghosted solution vector
1700 : * @return true if the solution was modified, false otherwise
1701 : */
1702 : virtual bool updateSolution(NumericVector<libMesh::Number> & vec_solution,
1703 : NumericVector<libMesh::Number> & ghosted_solution);
1704 :
1705 : /**
1706 : * Perform cleanup tasks after application of predictor to solution vector
1707 : * @param ghosted_solution Ghosted solution vector
1708 : */
1709 : virtual void predictorCleanup(NumericVector<libMesh::Number> & ghosted_solution);
1710 :
1711 : virtual void computeBounds(libMesh::NonlinearImplicitSystem & sys,
1712 : NumericVector<libMesh::Number> & lower,
1713 : NumericVector<libMesh::Number> & upper);
1714 : virtual void computeNearNullSpace(libMesh::NonlinearImplicitSystem & sys,
1715 : std::vector<NumericVector<libMesh::Number> *> & sp);
1716 : virtual void computeNullSpace(libMesh::NonlinearImplicitSystem & sys,
1717 : std::vector<NumericVector<libMesh::Number> *> & sp);
1718 : virtual void computeTransposeNullSpace(libMesh::NonlinearImplicitSystem & sys,
1719 : std::vector<NumericVector<libMesh::Number> *> & sp);
1720 : virtual void computePostCheck(libMesh::NonlinearImplicitSystem & sys,
1721 : const NumericVector<libMesh::Number> & old_soln,
1722 : NumericVector<libMesh::Number> & search_direction,
1723 : NumericVector<libMesh::Number> & new_soln,
1724 : bool & changed_search_direction,
1725 : bool & changed_new_soln);
1726 :
1727 : virtual void computeIndicatorsAndMarkers();
1728 : virtual void computeIndicators();
1729 : virtual void computeMarkers();
1730 :
1731 : virtual void addResidual(const THREAD_ID tid) override;
1732 : virtual void addResidualNeighbor(const THREAD_ID tid) override;
1733 : virtual void addResidualLower(const THREAD_ID tid) override;
1734 : virtual void addResidualScalar(const THREAD_ID tid = 0);
1735 :
1736 : virtual void cacheResidual(const THREAD_ID tid) override;
1737 : virtual void cacheResidualNeighbor(const THREAD_ID tid) override;
1738 : virtual void addCachedResidual(const THREAD_ID tid) override;
1739 :
1740 : /**
1741 : * Allows for all the residual contributions that are currently cached to be added directly into
1742 : * the vector passed in.
1743 : *
1744 : * @param residual The vector to add the cached contributions to.
1745 : * @param tid The thread id.
1746 : */
1747 : virtual void addCachedResidualDirectly(NumericVector<libMesh::Number> & residual,
1748 : const THREAD_ID tid);
1749 :
1750 : virtual void setResidual(NumericVector<libMesh::Number> & residual, const THREAD_ID tid) override;
1751 : virtual void setResidualNeighbor(NumericVector<libMesh::Number> & residual,
1752 : const THREAD_ID tid) override;
1753 :
1754 : virtual void addJacobian(const THREAD_ID tid) override;
1755 : virtual void addJacobianNeighbor(const THREAD_ID tid) override;
1756 : virtual void addJacobianNeighborLowerD(const THREAD_ID tid) override;
1757 : virtual void addJacobianLowerD(const THREAD_ID tid) override;
1758 : virtual void addJacobianBlockTags(libMesh::SparseMatrix<libMesh::Number> & jacobian,
1759 : unsigned int ivar,
1760 : unsigned int jvar,
1761 : const DofMap & dof_map,
1762 : std::vector<dof_id_type> & dof_indices,
1763 : const std::set<TagID> & tags,
1764 : const THREAD_ID tid);
1765 : virtual void addJacobianNeighbor(libMesh::SparseMatrix<libMesh::Number> & jacobian,
1766 : unsigned int ivar,
1767 : unsigned int jvar,
1768 : const DofMap & dof_map,
1769 : std::vector<dof_id_type> & dof_indices,
1770 : std::vector<dof_id_type> & neighbor_dof_indices,
1771 : const std::set<TagID> & tags,
1772 : const THREAD_ID tid) override;
1773 : virtual void addJacobianScalar(const THREAD_ID tid = 0);
1774 : virtual void addJacobianOffDiagScalar(unsigned int ivar, const THREAD_ID tid = 0);
1775 :
1776 : virtual void cacheJacobian(const THREAD_ID tid) override;
1777 : virtual void cacheJacobianNeighbor(const THREAD_ID tid) override;
1778 : virtual void addCachedJacobian(const THREAD_ID tid) override;
1779 :
1780 : virtual void prepareShapes(unsigned int var, const THREAD_ID tid) override;
1781 : virtual void prepareFaceShapes(unsigned int var, const THREAD_ID tid) override;
1782 : virtual void prepareNeighborShapes(unsigned int var, const THREAD_ID tid) override;
1783 :
1784 : // Displaced problem /////
1785 : virtual void addDisplacedProblem(std::shared_ptr<DisplacedProblem> displaced_problem);
1786 0 : virtual std::shared_ptr<const DisplacedProblem> getDisplacedProblem() const
1787 : {
1788 0 : return _displaced_problem;
1789 : }
1790 4746981 : virtual std::shared_ptr<DisplacedProblem> getDisplacedProblem() { return _displaced_problem; }
1791 :
1792 : virtual void updateGeomSearch(
1793 : GeometricSearchData::GeometricSearchType type = GeometricSearchData::ALL) override;
1794 : virtual void updateMortarMesh();
1795 :
1796 : void createMortarInterface(
1797 : const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
1798 : const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
1799 : bool on_displaced,
1800 : bool periodic,
1801 : const bool debug,
1802 : const bool correct_edge_dropping,
1803 : const Real minimum_projection_angle);
1804 :
1805 : /**
1806 : * Return the undisplaced or displaced mortar generation object associated with the provided
1807 : * boundaries and subdomains
1808 : */
1809 : ///@{
1810 : const AutomaticMortarGeneration &
1811 : getMortarInterface(const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
1812 : const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
1813 : bool on_displaced) const;
1814 :
1815 : AutomaticMortarGeneration &
1816 : getMortarInterface(const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
1817 : const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
1818 : bool on_displaced);
1819 : ///@}
1820 :
1821 : const std::unordered_map<std::pair<BoundaryID, BoundaryID>,
1822 : std::unique_ptr<AutomaticMortarGeneration>> &
1823 : getMortarInterfaces(bool on_displaced) const;
1824 :
1825 : virtual void possiblyRebuildGeomSearchPatches();
1826 :
1827 668336 : virtual GeometricSearchData & geomSearchData() override { return _geometric_search_data; }
1828 :
1829 : /**
1830 : * Communicate to the Resurector the name of the restart filer
1831 : * @param file_name The file name for restarting from
1832 : */
1833 : void setRestartFile(const std::string & file_name);
1834 :
1835 : /**
1836 : * @return A reference to the material property registry
1837 : */
1838 0 : const MaterialPropertyRegistry & getMaterialPropertyRegistry() const
1839 : {
1840 0 : return _material_prop_registry;
1841 : }
1842 :
1843 : /**
1844 : * Return a reference to the material property storage
1845 : * @return A const reference to the material property storage
1846 : */
1847 : ///@{
1848 : const MaterialPropertyStorage & getMaterialPropertyStorage() { return _material_props; }
1849 : const MaterialPropertyStorage & getBndMaterialPropertyStorage() { return _bnd_material_props; }
1850 : const MaterialPropertyStorage & getNeighborMaterialPropertyStorage()
1851 : {
1852 : return _neighbor_material_props;
1853 : }
1854 :
1855 : #ifdef MOOSE_KOKKOS_ENABLED
1856 : Moose::Kokkos::MaterialPropertyStorage & getKokkosMaterialPropertyStorage()
1857 : {
1858 : return _kokkos_material_props;
1859 : }
1860 : Moose::Kokkos::MaterialPropertyStorage & getKokkosBndMaterialPropertyStorage()
1861 : {
1862 : return _kokkos_bnd_material_props;
1863 : }
1864 : Moose::Kokkos::MaterialPropertyStorage & getKokkosNeighborMaterialPropertyStorage()
1865 : {
1866 : return _kokkos_neighbor_material_props;
1867 : }
1868 : #endif
1869 : ///@}
1870 :
1871 : /**
1872 : * Return indicator/marker storage.
1873 : */
1874 : ///@{
1875 5152 : const MooseObjectWarehouse<Indicator> & getIndicatorWarehouse() { return _indicators; }
1876 5152 : const MooseObjectWarehouse<InternalSideIndicatorBase> & getInternalSideIndicatorWarehouse()
1877 : {
1878 5152 : return _internal_side_indicators;
1879 : }
1880 7068 : const MooseObjectWarehouse<Marker> & getMarkerWarehouse() { return _markers; }
1881 : ///@}
1882 :
1883 : /**
1884 : * Return InitialCondition storage
1885 : */
1886 4453766 : const InitialConditionWarehouse & getInitialConditionWarehouse() const { return _ics; }
1887 :
1888 : /**
1889 : * Return FVInitialCondition storage
1890 : */
1891 10850 : const FVInitialConditionWarehouse & getFVInitialConditionWarehouse() const { return _fv_ics; }
1892 :
1893 : /**
1894 : * Get the solver parameters
1895 : */
1896 : SolverParams & solverParams(unsigned int solver_sys_num = 0);
1897 :
1898 : /**
1899 : * const version
1900 : */
1901 : const SolverParams & solverParams(unsigned int solver_sys_num = 0) const;
1902 :
1903 : #ifdef LIBMESH_ENABLE_AMR
1904 : // Adaptivity /////
1905 162635 : Adaptivity & adaptivity() { return _adaptivity; }
1906 : virtual void initialAdaptMesh();
1907 :
1908 : /**
1909 : * @returns Whether or not the mesh was changed
1910 : */
1911 : virtual bool adaptMesh();
1912 :
1913 : /**
1914 : * @return The number of adaptivity cycles completed.
1915 : */
1916 183 : unsigned int getNumCyclesCompleted() { return _cycles_completed; }
1917 :
1918 : /**
1919 : * Return a Boolean indicating whether initial AMR is turned on.
1920 : */
1921 : bool hasInitialAdaptivity() const { return _adaptivity.getInitialSteps() > 0; }
1922 : #else
1923 : /**
1924 : * Return a Boolean indicating whether initial AMR is turned on.
1925 : */
1926 : bool hasInitialAdaptivity() const { return false; }
1927 : #endif // LIBMESH_ENABLE_AMR
1928 :
1929 : /// Create XFEM controller object
1930 : void initXFEM(std::shared_ptr<XFEMInterface> xfem);
1931 :
1932 : /// Get a pointer to the XFEM controller object
1933 : std::shared_ptr<XFEMInterface> getXFEM() { return _xfem; }
1934 :
1935 : /// Find out whether the current analysis is using XFEM
1936 1313677 : bool haveXFEM() { return _xfem != nullptr; }
1937 :
1938 : /// Update the mesh due to changing XFEM cuts
1939 : virtual bool updateMeshXFEM();
1940 :
1941 : /**
1942 : * Update data after a mesh change.
1943 : * Iff intermediate_change is true, only perform updates as
1944 : * necessary to prepare for another mesh change
1945 : * immediately-subsequent. An example of data that is not updated during an intermediate change is
1946 : * libMesh System matrix data. An example of data that \emph is updated during an intermediate
1947 : * change is libMesh System vectors. These vectors are projected or restricted based off of
1948 : * adaptive mesh refinement or the changing of element subdomain IDs. The flags \p contract_mesh
1949 : * and \p clean_refinement_flags should generally only be set to true when the mesh has changed
1950 : * due to mesh refinement. \p contract_mesh deletes children of coarsened elements and renumbers
1951 : * nodes and elements. \p clean_refinement_flags resets refinement flags such that any subsequent
1952 : * calls to \p System::restrict_vectors or \p System::prolong_vectors before another AMR step do
1953 : * not mistakenly attempt to re-do the restriction/prolongation which occurred in this method
1954 : */
1955 : virtual void
1956 : meshChanged(bool intermediate_change, bool contract_mesh, bool clean_refinement_flags);
1957 :
1958 : /**
1959 : * Register an object that derives from MeshChangedInterface
1960 : * to be notified when the mesh changes.
1961 : */
1962 : void notifyWhenMeshChanges(MeshChangedInterface * mci);
1963 :
1964 : /**
1965 : * Register an object that derives from MeshDisplacedInterface
1966 : * to be notified when the displaced mesh gets updated.
1967 : */
1968 : void notifyWhenMeshDisplaces(MeshDisplacedInterface * mdi);
1969 :
1970 : /**
1971 : * Initialize stateful properties for elements in a specific \p elem_range
1972 : * This is needed when elements/boundary nodes are added to a specific subdomain
1973 : * at an intermediate step
1974 : */
1975 : void initElementStatefulProps(const libMesh::ConstElemRange & elem_range, const bool threaded);
1976 :
1977 : #ifdef MOOSE_KOKKOS_ENABLED
1978 : void initKokkosStatefulProps();
1979 : #endif
1980 :
1981 : /**
1982 : * Method called to perform a series of sanity checks before a simulation is run. This method
1983 : * doesn't return when errors are found, instead it generally calls mooseError() directly.
1984 : */
1985 : virtual void checkProblemIntegrity();
1986 :
1987 : void registerRandomInterface(RandomInterface & random_interface, const std::string & name);
1988 :
1989 : /**
1990 : * Set flag that Jacobian is constant (for optimization purposes)
1991 : * @param state True if the Jacobian is constant, false otherwise
1992 : */
1993 4621 : void setConstJacobian(bool state) { _const_jacobian = state; }
1994 :
1995 : /**
1996 : * Set flag to indicate whether kernel coverage checks should be performed. This check makes
1997 : * sure that at least one kernel is active on all subdomains in the domain (default: true).
1998 : */
1999 : void setKernelCoverageCheck(CoverageCheckMode mode) { _kernel_coverage_check = mode; }
2000 :
2001 : /**
2002 : * Set flag to indicate whether kernel coverage checks should be performed. This check makes
2003 : * sure that at least one kernel is active on all subdomains in the domain (default: true).
2004 : */
2005 : void setKernelCoverageCheck(bool flag)
2006 : {
2007 : _kernel_coverage_check = flag ? CoverageCheckMode::TRUE : CoverageCheckMode::FALSE;
2008 : }
2009 :
2010 : /**
2011 : * Set flag to indicate whether material coverage checks should be performed. This check makes
2012 : * sure that at least one material is active on all subdomains in the domain if any material is
2013 : * supplied. If no materials are supplied anywhere, a simulation is still considered OK as long as
2014 : * no properties are being requested anywhere.
2015 : */
2016 : void setMaterialCoverageCheck(CoverageCheckMode mode) { _material_coverage_check = mode; }
2017 :
2018 : /**
2019 : * Set flag to indicate whether material coverage checks should be performed. This check makes
2020 : * sure that at least one material is active on all subdomains in the domain if any material is
2021 : * supplied. If no materials are supplied anywhere, a simulation is still considered OK as long as
2022 : * no properties are being requested anywhere.
2023 : */
2024 : void setMaterialCoverageCheck(bool flag)
2025 : {
2026 : _material_coverage_check = flag ? CoverageCheckMode::TRUE : CoverageCheckMode::FALSE;
2027 : }
2028 :
2029 : /**
2030 : * Toggle parallel barrier messaging (defaults to on).
2031 : */
2032 : void setParallelBarrierMessaging(bool flag) { _parallel_barrier_messaging = flag; }
2033 :
2034 : /// Make the problem be verbose
2035 : void setVerboseProblem(bool verbose);
2036 :
2037 : /**
2038 : * Whether or not to use verbose printing for MultiApps.
2039 : */
2040 216659 : bool verboseMultiApps() const { return _verbose_multiapps; }
2041 :
2042 : /**
2043 : * Calls parentOutputPositionChanged() on all sub apps.
2044 : */
2045 : void parentOutputPositionChanged();
2046 :
2047 : ///@{
2048 : /**
2049 : * These methods are used to determine whether stateful material properties need to be stored on
2050 : * internal sides. There are five situations where this may be the case: 1) DGKernels
2051 : * 2) IntegratedBCs 3)InternalSideUserObjects 4)ElementalAuxBCs 5)InterfaceUserObjects
2052 : *
2053 : * Method 1:
2054 : * @param bnd_id the boundary id for which to see if stateful material properties need to be
2055 : * stored
2056 : * @param tid the THREAD_ID of the caller
2057 : * @return Boolean indicating whether material properties need to be stored
2058 : *
2059 : * Method 2:
2060 : * @param subdomain_id the subdomain id for which to see if stateful material properties need to
2061 : * be stored
2062 : * @param tid the THREAD_ID of the caller
2063 : * @return Boolean indicating whether material properties need to be stored
2064 : */
2065 : bool needBoundaryMaterialOnSide(BoundaryID bnd_id, const THREAD_ID tid);
2066 : bool needInterfaceMaterialOnSide(BoundaryID bnd_id, const THREAD_ID tid);
2067 : bool needInternalNeighborSideMaterial(SubdomainID subdomain_id, const THREAD_ID tid);
2068 : ///@}
2069 :
2070 : /**
2071 : * Dimension of the subspace spanned by vectors with a given prefix.
2072 : * @param prefix Prefix of the vectors spanning the subspace.
2073 : */
2074 973160 : unsigned int subspaceDim(const std::string & prefix) const
2075 : {
2076 973160 : if (_subspace_dim.count(prefix))
2077 973160 : return _subspace_dim.find(prefix)->second;
2078 : else
2079 0 : return 0;
2080 : }
2081 :
2082 : /*
2083 : * Return a reference to the material warehouse of *all* Material objects.
2084 : */
2085 5787348 : const MaterialWarehouse & getMaterialWarehouse() const { return _all_materials; }
2086 :
2087 : /*
2088 : * Return a reference to the material warehouse of Material objects to be computed.
2089 : */
2090 11952 : const MaterialWarehouse & getRegularMaterialsWarehouse() const { return _materials; }
2091 10671 : const MaterialWarehouse & getDiscreteMaterialWarehouse() const { return _discrete_materials; }
2092 12069 : const MaterialWarehouse & getInterfaceMaterialsWarehouse() const { return _interface_materials; }
2093 :
2094 : #ifdef MOOSE_KOKKOS_ENABLED
2095 : /*
2096 : * Return a reference to the material warehouse of Kokkos Material objects to be computed.
2097 : */
2098 358900 : const MaterialWarehouse & getKokkosMaterialsWarehouse() const { return _kokkos_materials; }
2099 : #endif
2100 :
2101 : /**
2102 : * Return a pointer to a MaterialBase object. If no_warn is true, suppress
2103 : * warning about retrieving a material reference potentially during the
2104 : * material's calculation.
2105 : *
2106 : * This will return enabled or disabled objects, the main purpose is for iterative materials.
2107 : */
2108 : std::shared_ptr<MaterialBase> getMaterial(std::string name,
2109 : Moose::MaterialDataType type,
2110 : const THREAD_ID tid = 0,
2111 : bool no_warn = false);
2112 :
2113 : /**
2114 : * @return The MaterialData for the type \p type for thread \p tid
2115 : */
2116 : MaterialData & getMaterialData(Moose::MaterialDataType type,
2117 : const THREAD_ID tid = 0,
2118 : const MooseObject * object = nullptr) const;
2119 :
2120 : #ifdef MOOSE_KOKKOS_ENABLED
2121 : /**
2122 : * @return The Kokkos MaterialData for the type \p type for thread \p tid
2123 : */
2124 : MaterialData & getKokkosMaterialData(Moose::MaterialDataType type,
2125 : const MooseObject * object = nullptr) const;
2126 : #endif
2127 :
2128 : /**
2129 : * @return The consumers of the MaterialPropertyStorage for the type \p type
2130 : */
2131 : const std::set<const MooseObject *> &
2132 : getMaterialPropertyStorageConsumers(Moose::MaterialDataType type) const;
2133 :
2134 : #ifdef MOOSE_KOKKOS_ENABLED
2135 : /**
2136 : * @return The consumers of the Kokkos MaterialPropertyStorage for the type \p type
2137 : */
2138 : const std::set<const MooseObject *> &
2139 : getKokkosMaterialPropertyStorageConsumers(Moose::MaterialDataType type) const;
2140 : #endif
2141 :
2142 : /**
2143 : * @returns Whether the original matrix nonzero pattern is restored before each Jacobian assembly
2144 : */
2145 526721 : bool restoreOriginalNonzeroPattern() const { return _restore_original_nonzero_pattern; }
2146 :
2147 : /**
2148 : * Will return True if the user wants to get an error when
2149 : * a nonzero is reallocated in the Jacobian by PETSc
2150 : */
2151 543691 : bool errorOnJacobianNonzeroReallocation() const
2152 : {
2153 543691 : return _error_on_jacobian_nonzero_reallocation;
2154 : }
2155 :
2156 306 : void setErrorOnJacobianNonzeroReallocation(bool state)
2157 : {
2158 306 : _error_on_jacobian_nonzero_reallocation = state;
2159 306 : }
2160 :
2161 : /**
2162 : * Will return True if the executioner in use requires preserving the sparsity pattern of the
2163 : * matrices being formed during the solve. This is usually the Jacobian.
2164 : */
2165 : bool preserveMatrixSparsityPattern() const { return _preserve_matrix_sparsity_pattern; };
2166 :
2167 : /// Set whether the sparsity pattern of the matrices being formed during the solve (usually the Jacobian)
2168 : /// should be preserved. This global setting can be retrieved by kernels, notably those using AD, to decide
2169 : /// whether to take additional care to preserve the sparsity pattern
2170 : void setPreserveMatrixSparsityPattern(bool preserve);
2171 :
2172 : /**
2173 : * Will return true if zeros in the Jacobian are to be dropped from the sparsity pattern.
2174 : * Note that this can make preserving the matrix sparsity pattern impossible.
2175 : */
2176 536269 : bool ignoreZerosInJacobian() const { return _ignore_zeros_in_jacobian; }
2177 :
2178 : /// Set whether the zeros in the Jacobian should be dropped from the sparsity pattern
2179 : void setIgnoreZerosInJacobian(bool state) { _ignore_zeros_in_jacobian = state; }
2180 :
2181 : /**
2182 : * Whether or not to accept the solution based on its invalidity.
2183 : *
2184 : * If this returns false, it means that an invalid solution was encountered
2185 : * (an error) that was not allowed.
2186 : */
2187 : bool acceptInvalidSolution() const;
2188 : /**
2189 : * Whether to accept / allow an invalid solution
2190 : */
2191 340119 : bool allowInvalidSolution() const { return _allow_invalid_solution; }
2192 :
2193 : /**
2194 : * Whether or not to print out the invalid solutions summary table in console
2195 : */
2196 691 : bool showInvalidSolutionConsole() const { return _show_invalid_solution_console; }
2197 :
2198 : /**
2199 : * Whether or not the solution invalid warnings are printed out immediately
2200 : */
2201 97513 : bool immediatelyPrintInvalidSolution() const { return _immediately_print_invalid_solution; }
2202 :
2203 : /// Returns whether or not this Problem has a TimeIntegrator
2204 32502 : bool hasTimeIntegrator() const { return _has_time_integrator; }
2205 :
2206 : ///@{
2207 : /**
2208 : * Return/set the current execution flag.
2209 : *
2210 : * Returns EXEC_NONE when not being executed.
2211 : * @see FEProblemBase::execute
2212 : */
2213 : const ExecFlagType & getCurrentExecuteOnFlag() const;
2214 : void setCurrentExecuteOnFlag(const ExecFlagType &);
2215 : ///@}
2216 :
2217 : /**
2218 : * Convenience function for performing execution of MOOSE systems.
2219 : */
2220 : virtual void execute(const ExecFlagType & exec_type);
2221 : virtual void executeAllObjects(const ExecFlagType & exec_type);
2222 :
2223 0 : virtual Executor & getExecutor(const std::string & name) { return _app.getExecutor(name); }
2224 :
2225 : /**
2226 : * Call compute methods on UserObjects.
2227 : */
2228 : virtual void computeUserObjects(const ExecFlagType & type, const Moose::AuxGroup & group);
2229 :
2230 : /**
2231 : * Compute an user object with the given name
2232 : */
2233 : virtual void computeUserObjectByName(const ExecFlagType & type,
2234 : const Moose::AuxGroup & group,
2235 : const std::string & name);
2236 :
2237 : /**
2238 : * Set a flag that indicated that user required values for the previous Newton iterate
2239 : */
2240 : void needsPreviousNewtonIteration(bool state);
2241 :
2242 : /**
2243 : * Check to see whether we need to compute the variable values of the previous Newton iterate
2244 : * @return true if the user required values of the previous Newton iterate
2245 : */
2246 : bool needsPreviousNewtonIteration() const;
2247 :
2248 : ///@{
2249 : /**
2250 : * Convenience zeros
2251 : */
2252 : std::vector<Real> _real_zero;
2253 : std::vector<VariableValue> _scalar_zero;
2254 : std::vector<VariableValue> _zero;
2255 : std::vector<VariablePhiValue> _phi_zero;
2256 : std::vector<MooseArray<ADReal>> _ad_zero;
2257 : std::vector<VariableGradient> _grad_zero;
2258 : std::vector<MooseArray<ADRealVectorValue>> _ad_grad_zero;
2259 : std::vector<VariablePhiGradient> _grad_phi_zero;
2260 : std::vector<VariableSecond> _second_zero;
2261 : std::vector<MooseArray<ADRealTensorValue>> _ad_second_zero;
2262 : std::vector<VariablePhiSecond> _second_phi_zero;
2263 : std::vector<Point> _point_zero;
2264 : std::vector<VectorVariableValue> _vector_zero;
2265 : std::vector<VectorVariableCurl> _vector_curl_zero;
2266 : ///@}
2267 :
2268 : /**
2269 : * Reference to the control logic warehouse.
2270 : */
2271 64146 : ExecuteMooseObjectWarehouse<Control> & getControlWarehouse() { return _control_warehouse; }
2272 :
2273 : /**
2274 : * Performs setup and execute calls for Control objects.
2275 : */
2276 : void executeControls(const ExecFlagType & exec_type);
2277 :
2278 : /**
2279 : * Performs setup and execute calls for Sampler objects.
2280 : */
2281 : void executeSamplers(const ExecFlagType & exec_type);
2282 :
2283 : /**
2284 : * Update the active objects in the warehouses
2285 : */
2286 : virtual void updateActiveObjects();
2287 :
2288 : /**
2289 : * Register a MOOSE object dependency so we can either order
2290 : * operations properly or report when we cannot.
2291 : * a -> b (a depends on b)
2292 : */
2293 : void reportMooseObjectDependency(MooseObject * a, MooseObject * b);
2294 :
2295 97135 : ExecuteMooseObjectWarehouse<MultiApp> & getMultiAppWarehouse() { return _multi_apps; }
2296 :
2297 : /**
2298 : * Returns _has_jacobian
2299 : */
2300 : bool hasJacobian() const;
2301 :
2302 : /**
2303 : * Returns _const_jacobian (whether a MOOSE object has specified that
2304 : * the Jacobian is the same as the previous time it was computed)
2305 : */
2306 : bool constJacobian() const;
2307 :
2308 : /**
2309 : * Adds an Output object.
2310 : */
2311 : void addOutput(const std::string &, const std::string &, InputParameters &);
2312 :
2313 33617546 : inline TheWarehouse & theWarehouse() const { return _app.theWarehouse(); }
2314 :
2315 : /**
2316 : * If or not to reuse the base vector for matrix-free calculation
2317 : */
2318 63747 : void setSNESMFReuseBase(bool reuse, bool set_by_user)
2319 : {
2320 63747 : _snesmf_reuse_base = reuse, _snesmf_reuse_base_set_by_user = set_by_user;
2321 63747 : }
2322 :
2323 : /**
2324 : * Return a flag that indicates if we are reusing the vector base
2325 : */
2326 322072 : bool useSNESMFReuseBase() { return _snesmf_reuse_base; }
2327 :
2328 : /**
2329 : * Set a flag that indicates if we want to skip exception and stop solve
2330 : */
2331 63747 : void skipExceptionCheck(bool skip_exception_check)
2332 : {
2333 63747 : _skip_exception_check = skip_exception_check;
2334 63747 : }
2335 :
2336 : /**
2337 : * Return a flag to indicate if _snesmf_reuse_base is set by users
2338 : */
2339 : bool isSNESMFReuseBaseSetbyUser() { return _snesmf_reuse_base_set_by_user; }
2340 :
2341 : /**
2342 : * If PETSc options are already inserted
2343 : */
2344 1126 : bool & petscOptionsInserted() { return _is_petsc_options_inserted; }
2345 :
2346 : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
2347 26 : PetscOptions & petscOptionsDatabase() { return _petsc_option_data_base; }
2348 : #endif
2349 :
2350 : /// Set boolean flag to true to store solution time derivative
2351 63988 : virtual void setUDotRequested(const bool u_dot_requested) { _u_dot_requested = u_dot_requested; }
2352 :
2353 : /// Set boolean flag to true to store solution second time derivative
2354 328 : virtual void setUDotDotRequested(const bool u_dotdot_requested)
2355 : {
2356 328 : _u_dotdot_requested = u_dotdot_requested;
2357 328 : }
2358 :
2359 : /// Set boolean flag to true to store old solution time derivative
2360 328 : virtual void setUDotOldRequested(const bool u_dot_old_requested)
2361 : {
2362 328 : _u_dot_old_requested = u_dot_old_requested;
2363 328 : }
2364 :
2365 : /// Set boolean flag to true to store old solution second time derivative
2366 328 : virtual void setUDotDotOldRequested(const bool u_dotdot_old_requested)
2367 : {
2368 328 : _u_dotdot_old_requested = u_dotdot_old_requested;
2369 328 : }
2370 :
2371 : /// Get boolean flag to check whether solution time derivative needs to be stored
2372 63866 : virtual bool uDotRequested() { return _u_dot_requested; }
2373 :
2374 : /// Get boolean flag to check whether solution second time derivative needs to be stored
2375 95803 : virtual bool uDotDotRequested() { return _u_dotdot_requested; }
2376 :
2377 : /// Get boolean flag to check whether old solution time derivative needs to be stored
2378 63866 : virtual bool uDotOldRequested()
2379 : {
2380 63866 : if (_u_dot_old_requested && !_u_dot_requested)
2381 0 : mooseError("FEProblemBase: When requesting old time derivative of solution, current time "
2382 : "derivative of solution should also be stored. Please set `u_dot_requested` to "
2383 : "true using setUDotRequested.");
2384 :
2385 63866 : return _u_dot_old_requested;
2386 : }
2387 :
2388 : /// Get boolean flag to check whether old solution second time derivative needs to be stored
2389 63866 : virtual bool uDotDotOldRequested()
2390 : {
2391 63866 : if (_u_dotdot_old_requested && !_u_dotdot_requested)
2392 0 : mooseError("FEProblemBase: When requesting old second time derivative of solution, current "
2393 : "second time derivation of solution should also be stored. Please set "
2394 : "`u_dotdot_requested` to true using setUDotDotRequested.");
2395 63866 : return _u_dotdot_old_requested;
2396 : }
2397 :
2398 : using SubProblem::haveADObjects;
2399 : void haveADObjects(bool have_ad_objects) override;
2400 :
2401 : // Whether or not we should solve this system
2402 353954 : bool shouldSolve() const { return _solve; }
2403 :
2404 : /**
2405 : * Returns the mortar data object
2406 : */
2407 : const MortarInterfaceWarehouse & mortarData() const { return *_mortar_data; }
2408 1448 : MortarInterfaceWarehouse & mortarData() { return *_mortar_data; }
2409 :
2410 : /**
2411 : * Whether the simulation has neighbor coupling
2412 : */
2413 0 : virtual bool hasNeighborCoupling() const { return _has_internal_edge_residual_objects; }
2414 :
2415 : /**
2416 : * Whether the simulation has mortar coupling
2417 : */
2418 0 : virtual bool hasMortarCoupling() const { return _has_mortar; }
2419 :
2420 : using SubProblem::computingNonlinearResid;
2421 : void computingNonlinearResid(bool computing_nonlinear_residual) final;
2422 :
2423 : using SubProblem::currentlyComputingResidual;
2424 : void setCurrentlyComputingResidual(bool currently_computing_residual) final;
2425 :
2426 : /**
2427 : * Set the number of steps in a grid sequences
2428 : */
2429 63727 : void numGridSteps(unsigned int num_grid_steps) { _num_grid_steps = num_grid_steps; }
2430 :
2431 : /**
2432 : * uniformly refine the problem mesh(es). This will also prolong the the solution, and in order
2433 : * for that to be safe, we can only perform one refinement at a time
2434 : */
2435 : void uniformRefine();
2436 :
2437 : using SubProblem::automaticScaling;
2438 : void automaticScaling(bool automatic_scaling) override;
2439 :
2440 : ///@{
2441 : /**
2442 : * Helpers for calling the necessary setup/execute functions for the supplied objects
2443 : */
2444 : template <typename T>
2445 : static void objectSetupHelper(const std::vector<T *> & objects, const ExecFlagType & exec_flag);
2446 : template <typename T>
2447 : static void objectExecuteHelper(const std::vector<T *> & objects);
2448 : ///@}
2449 :
2450 : /**
2451 : * reinitialize FE objects on a given element on a given side at a given set of reference
2452 : * points and then compute variable data. Note that this method makes no assumptions about what's
2453 : * been called beforehand, e.g. you don't have to call some prepare method before this one. This
2454 : * is an all-in-one reinit
2455 : */
2456 : virtual void reinitElemFaceRef(const Elem * elem,
2457 : unsigned int side,
2458 : Real tolerance,
2459 : const std::vector<Point> * const pts,
2460 : const std::vector<Real> * const weights = nullptr,
2461 : const THREAD_ID tid = 0) override;
2462 :
2463 : /**
2464 : * reinitialize FE objects on a given neighbor element on a given side at a given set of reference
2465 : * points and then compute variable data. Note that this method makes no assumptions about what's
2466 : * been called beforehand, e.g. you don't have to call some prepare method before this one. This
2467 : * is an all-in-one reinit
2468 : */
2469 : virtual void reinitNeighborFaceRef(const Elem * neighbor_elem,
2470 : unsigned int neighbor_side,
2471 : Real tolerance,
2472 : const std::vector<Point> * const pts,
2473 : const std::vector<Real> * const weights = nullptr,
2474 : const THREAD_ID tid = 0) override;
2475 :
2476 : /**
2477 : * @return whether to perform a boundary condition integrity check for finite volume
2478 : */
2479 3466 : bool fvBCsIntegrityCheck() const { return _fv_bcs_integrity_check; }
2480 :
2481 : /**
2482 : * @param fv_bcs_integrity_check Whether to perform a boundary condition integrity check for
2483 : * finite volume
2484 : */
2485 : void fvBCsIntegrityCheck(bool fv_bcs_integrity_check);
2486 :
2487 : /**
2488 : * Get the materials and variables potentially needed for FV
2489 : * @param block_id SubdomainID The subdomain id that we want to retrieve materials for
2490 : * @param face_materials The face materials container that we will fill
2491 : * @param neighbor_materials The neighbor materials container that we will fill
2492 : * @param variables The variables container that we will fill that our materials depend on
2493 : * @param tid The thread id
2494 : */
2495 : void getFVMatsAndDependencies(SubdomainID block_id,
2496 : std::vector<std::shared_ptr<MaterialBase>> & face_materials,
2497 : std::vector<std::shared_ptr<MaterialBase>> & neighbor_materials,
2498 : std::set<MooseVariableFieldBase *> & variables,
2499 : const THREAD_ID tid);
2500 :
2501 : /**
2502 : * Resize material data
2503 : * @param data_type The type of material data to resize
2504 : * @param nqp The number of quadrature points to resize for
2505 : * @param tid The thread ID
2506 : */
2507 : void resizeMaterialData(Moose::MaterialDataType data_type, unsigned int nqp, const THREAD_ID tid);
2508 :
2509 741 : bool haveDisplaced() const override final { return _displaced_problem.get(); }
2510 :
2511 : /// Whether we have linear convergence objects
2512 : bool hasLinearConvergenceObjects() const;
2513 : /**
2514 : * Sets the nonlinear convergence object name(s) if there is one
2515 : */
2516 : void setNonlinearConvergenceNames(const std::vector<ConvergenceName> & convergence_names);
2517 : /**
2518 : * Sets the linear convergence object name(s) if there is one
2519 : */
2520 : void setLinearConvergenceNames(const std::vector<ConvergenceName> & convergence_names);
2521 : /**
2522 : * Sets the MultiApp fixed point convergence object name if there is one
2523 : */
2524 : void setMultiAppFixedPointConvergenceName(const ConvergenceName & convergence_name);
2525 : /**
2526 : * Sets the steady-state detection convergence object name if there is one
2527 : */
2528 : void setSteadyStateConvergenceName(const ConvergenceName & convergence_name);
2529 :
2530 : /**
2531 : * Gets the nonlinear system convergence object name(s).
2532 : */
2533 : const std::vector<ConvergenceName> & getNonlinearConvergenceNames() const;
2534 : /**
2535 : * Gets the linear convergence object name(s).
2536 : */
2537 : const std::vector<ConvergenceName> & getLinearConvergenceNames() const;
2538 : /**
2539 : * Gets the MultiApp fixed point convergence object name.
2540 : */
2541 : const ConvergenceName & getMultiAppFixedPointConvergenceName() const;
2542 : /**
2543 : * Gets the steady-state detection convergence object name.
2544 : */
2545 : const ConvergenceName & getSteadyStateConvergenceName() const;
2546 :
2547 : /**
2548 : * Setter for whether we're computing the scaling jacobian
2549 : */
2550 1204 : void computingScalingJacobian(bool computing_scaling_jacobian)
2551 : {
2552 1204 : _computing_scaling_jacobian = computing_scaling_jacobian;
2553 1204 : }
2554 :
2555 80251785 : bool computingScalingJacobian() const override final { return _computing_scaling_jacobian; }
2556 :
2557 : /**
2558 : * Setter for whether we're computing the scaling residual
2559 : */
2560 100 : void computingScalingResidual(bool computing_scaling_residual)
2561 : {
2562 100 : _computing_scaling_residual = computing_scaling_residual;
2563 100 : }
2564 :
2565 : /**
2566 : * @return whether we are currently computing a residual for automatic scaling purposes
2567 : */
2568 6866195 : bool computingScalingResidual() const override final { return _computing_scaling_residual; }
2569 :
2570 : /**
2571 : * @return the coordinate transformation object that describes how to transform this problem's
2572 : * coordinate system into the canonical/reference coordinate system
2573 : */
2574 : MooseAppCoordTransform & coordTransform();
2575 :
2576 185825245 : virtual std::size_t numNonlinearSystems() const override { return _num_nl_sys; }
2577 :
2578 440995 : virtual std::size_t numLinearSystems() const override { return _num_linear_sys; }
2579 :
2580 12183072 : virtual std::size_t numSolverSystems() const override { return _num_nl_sys + _num_linear_sys; }
2581 :
2582 : /// Check if the solver system is nonlinear
2583 233581 : bool isSolverSystemNonlinear(const unsigned int sys_num) { return sys_num < _num_nl_sys; }
2584 :
2585 : virtual unsigned int currentNlSysNum() const override;
2586 :
2587 : virtual unsigned int currentLinearSysNum() const override;
2588 :
2589 : /**
2590 : * @return the nonlinear system number corresponding to the provided \p nl_sys_name
2591 : */
2592 : virtual unsigned int nlSysNum(const NonlinearSystemName & nl_sys_name) const override;
2593 :
2594 : /**
2595 : * @return the linear system number corresponding to the provided \p linear_sys_name
2596 : */
2597 : unsigned int linearSysNum(const LinearSystemName & linear_sys_name) const override;
2598 :
2599 : /**
2600 : * @return the solver system number corresponding to the provided \p solver_sys_name
2601 : */
2602 : unsigned int solverSysNum(const SolverSystemName & solver_sys_name) const override;
2603 :
2604 : /**
2605 : * @return the system number for the provided \p variable_name
2606 : * Can be nonlinear or auxiliary
2607 : */
2608 : unsigned int systemNumForVariable(const VariableName & variable_name) const;
2609 :
2610 : /// Whether it will skip further residual evaluations and fail the next nonlinear convergence check(s)
2611 2253419 : bool getFailNextNonlinearConvergenceCheck() const { return getFailNextSystemConvergenceCheck(); }
2612 : /// Whether it will fail the next system convergence check(s), triggering failed step behavior
2613 2256053 : bool getFailNextSystemConvergenceCheck() const { return _fail_next_system_convergence_check; }
2614 :
2615 : /// Skip further residual evaluations and fail the next nonlinear convergence check(s)
2616 98 : void setFailNextNonlinearConvergenceCheck() { setFailNextSystemConvergenceCheck(); }
2617 : /// Tell the problem that the system(s) cannot be considered converged next time convergence is checked
2618 98 : void setFailNextSystemConvergenceCheck() { _fail_next_system_convergence_check = true; }
2619 :
2620 : /// Tell the problem that the nonlinear convergence check(s) may proceed as normal
2621 212 : void resetFailNextNonlinearConvergenceCheck() { resetFailNextSystemConvergenceCheck(); }
2622 : /// Tell the problem that the system convergence check(s) may proceed as normal
2623 212 : void resetFailNextSystemConvergenceCheck() { _fail_next_system_convergence_check = false; }
2624 :
2625 : /*
2626 : * Set the status of loop order of execution printing
2627 : * @param print_exec set of execution flags to print on
2628 : */
2629 272 : void setExecutionPrinting(const ExecFlagEnum & print_exec) { _print_execution_on = print_exec; }
2630 :
2631 : /**
2632 : * Check whether the problem should output execution orders at this time
2633 : */
2634 : bool shouldPrintExecution(const THREAD_ID tid) const;
2635 : /**
2636 : * Call \p reinit on mortar user objects with matching primary boundary ID, secondary boundary ID,
2637 : * and displacement characteristics
2638 : */
2639 : void reinitMortarUserObjects(BoundaryID primary_boundary_id,
2640 : BoundaryID secondary_boundary_id,
2641 : bool displaced);
2642 :
2643 : virtual const std::vector<VectorTag> & currentResidualVectorTags() const override;
2644 :
2645 : /**
2646 : * Class that is used as a parameter to set/clearCurrentResidualVectorTags that allows only
2647 : * blessed classes to call said methods
2648 : */
2649 : class CurrentResidualVectorTagsKey
2650 : {
2651 : friend class CrankNicolson;
2652 : friend class FEProblemBase;
2653 : CurrentResidualVectorTagsKey() {}
2654 : CurrentResidualVectorTagsKey(const CurrentResidualVectorTagsKey &) {}
2655 : };
2656 :
2657 : /**
2658 : * Set the current residual vector tag data structure based on the passed in tag IDs
2659 : */
2660 : void setCurrentResidualVectorTags(const std::set<TagID> & vector_tags);
2661 :
2662 : /**
2663 : * Clear the current residual vector tag data structure
2664 : */
2665 : void clearCurrentResidualVectorTags();
2666 :
2667 : /**
2668 : * Clear the current Jacobian matrix tag data structure ... if someone creates it
2669 : */
2670 3876064 : void clearCurrentJacobianMatrixTags() {}
2671 :
2672 7935 : virtual void needFV() override { _have_fv = true; }
2673 401538818 : virtual bool haveFV() const override { return _have_fv; }
2674 :
2675 57303418 : virtual bool hasNonlocalCoupling() const override { return _has_nonlocal_coupling; }
2676 :
2677 : /**
2678 : * Whether to identify variable groups in nonlinear systems. This affects dof ordering
2679 : */
2680 63562 : bool identifyVariableGroupsInNL() const { return _identify_variable_groups_in_nl; }
2681 :
2682 : virtual void setCurrentLowerDElem(const Elem * const lower_d_elem, const THREAD_ID tid) override;
2683 : virtual void setCurrentBoundaryID(BoundaryID bid, const THREAD_ID tid) override;
2684 :
2685 : /**
2686 : * @returns the nolinear system names in the problem
2687 : */
2688 139875 : const std::vector<NonlinearSystemName> & getNonlinearSystemNames() const { return _nl_sys_names; }
2689 : /**
2690 : * @returns the linear system names in the problem
2691 : */
2692 64021 : const std::vector<LinearSystemName> & getLinearSystemNames() const { return _linear_sys_names; }
2693 : /**
2694 : * @returns the solver system names in the problem
2695 : */
2696 550 : const std::vector<SolverSystemName> & getSolverSystemNames() const { return _solver_sys_names; }
2697 :
2698 : virtual const libMesh::CouplingMatrix & nonlocalCouplingMatrix(const unsigned i) const override;
2699 :
2700 : virtual bool checkNonlocalCouplingRequirement() const override;
2701 :
2702 112907 : virtual Moose::FEBackend feBackend() const { return Moose::FEBackend::LibMesh; }
2703 :
2704 : class CreateTaggedMatrixKey
2705 : {
2706 63721 : CreateTaggedMatrixKey() {}
2707 : CreateTaggedMatrixKey(const CreateTaggedMatrixKey &) {}
2708 :
2709 : friend class AddTaggedMatricesAction;
2710 : };
2711 :
2712 : void createTagMatrices(CreateTaggedMatrixKey);
2713 :
2714 : #ifdef MOOSE_KOKKOS_ENABLED
2715 : /**
2716 : * @returns whether any Kokkos object was added in the problem
2717 : */
2718 98483 : bool hasKokkosObjects() const { return _has_kokkos_objects; }
2719 : /**
2720 : * @returns whether any Kokkos residual object was added in the problem
2721 : */
2722 2535784 : bool hasKokkosResidualObjects() const { return _has_kokkos_residual_objects; }
2723 : #endif
2724 :
2725 : protected:
2726 : /**
2727 : * Deprecated. Users should switch to overriding the meshChanged which takes arguments
2728 : */
2729 7587 : virtual void meshChanged() {}
2730 :
2731 : /// Create extra tagged vectors and matrices
2732 : void createTagVectors();
2733 :
2734 : /// Create extra tagged solution vectors
2735 : void createTagSolutions();
2736 :
2737 : /**
2738 : * Update data after a mesh displaced.
2739 : */
2740 : virtual void meshDisplaced();
2741 :
2742 : /**
2743 : * Do generic system computations
2744 : */
2745 : void computeSystems(const ExecFlagType & type);
2746 :
2747 : MooseMesh & _mesh;
2748 :
2749 : private:
2750 : /// The EquationSystems object, wrapped for restart
2751 : Restartable::ManagedValue<RestartableEquationSystems> _req;
2752 :
2753 : /**
2754 : * Set the subproblem and system parameters for residual objects and log their addition
2755 : * @param ro_name The type of the residual object
2756 : * @param name The name of the residual object
2757 : * @param parameters The residual object parameters
2758 : * @param nl_sys_num The nonlinear system that the residual object belongs to
2759 : * @param base_name The base type of the residual object, e.g. Kernel, BoundaryCondition, etc.
2760 : * @param reinit_displaced A data member indicating whether a geometric concept should be reinit'd
2761 : * for the displaced problem. Examples of valid data members to pass in are \p
2762 : * _reinit_displaced_elem and \p _reinit_displaced_face
2763 : */
2764 : void setResidualObjectParamsAndLog(const std::string & ro_name,
2765 : const std::string & name,
2766 : InputParameters & parameters,
2767 : const unsigned int nl_sys_num,
2768 : const std::string & base_name,
2769 : bool & reinit_displaced);
2770 :
2771 : /**
2772 : * Set the subproblem and system parameters for auxiliary kernels and log their addition
2773 : * @param ak_name The type of the auxiliary kernel
2774 : * @param name The name of the auxiliary kernel
2775 : * @param parameters The auxiliary kernel parameters
2776 : * @param base_name The base type of the auxiliary kernel, i.e. AuxKernel or KokkosAuxKernel
2777 : */
2778 : void setAuxKernelParamsAndLog(const std::string & ak_name,
2779 : const std::string & name,
2780 : InputParameters & parameters,
2781 : const std::string & base_name);
2782 :
2783 : /**
2784 : * Make basic solver params for linear solves
2785 : */
2786 : static SolverParams makeLinearSolverParams();
2787 :
2788 : protected:
2789 : bool _initialized;
2790 :
2791 : /// Nonlinear system(s) convergence name(s)
2792 : std::optional<std::vector<ConvergenceName>> _nonlinear_convergence_names;
2793 : /// Linear system(s) convergence name(s) (if any)
2794 : std::optional<std::vector<ConvergenceName>> _linear_convergence_names;
2795 : /// MultiApp fixed point convergence name
2796 : std::optional<ConvergenceName> _multiapp_fixed_point_convergence_name;
2797 : /// Steady-state detection convergence name
2798 : std::optional<ConvergenceName> _steady_state_convergence_name;
2799 :
2800 : std::set<TagID> _fe_vector_tags;
2801 :
2802 : std::set<TagID> _fe_matrix_tags;
2803 :
2804 : /// Temporary storage for filtered vector tags for linear systems
2805 : std::set<TagID> _linear_vector_tags;
2806 :
2807 : /// Temporary storage for filtered matrix tags for linear systems
2808 : std::set<TagID> _linear_matrix_tags;
2809 :
2810 : /// Whether or not to actually solve the nonlinear system
2811 : const bool & _solve;
2812 :
2813 : bool _transient;
2814 : Real & _time;
2815 : Real & _time_old;
2816 : int & _t_step;
2817 : Real & _dt;
2818 : Real & _dt_old;
2819 :
2820 : /// Flag that the problem needs to add the default nonlinear convergence
2821 : bool _need_to_add_default_nonlinear_convergence;
2822 : /// Flag that the problem needs to add the default fixed point convergence
2823 : bool _need_to_add_default_multiapp_fixed_point_convergence;
2824 : /// Flag that the problem needs to add the default steady convergence
2825 : bool _need_to_add_default_steady_state_convergence;
2826 :
2827 : /// The linear system names
2828 : const std::vector<LinearSystemName> _linear_sys_names;
2829 :
2830 : /// The number of linear systems
2831 : const std::size_t _num_linear_sys;
2832 :
2833 : /// The vector of linear systems
2834 : std::vector<std::shared_ptr<LinearSystem>> _linear_systems;
2835 :
2836 : /// Map from linear system name to number
2837 : std::map<LinearSystemName, unsigned int> _linear_sys_name_to_num;
2838 :
2839 : /// The current linear system that we are solving
2840 : LinearSystem * _current_linear_sys;
2841 :
2842 : /// Boolean to check if we have the default nonlinear system
2843 : const bool _using_default_nl;
2844 :
2845 : /// The nonlinear system names
2846 : const std::vector<NonlinearSystemName> _nl_sys_names;
2847 :
2848 : /// The number of nonlinear systems
2849 : const std::size_t _num_nl_sys;
2850 :
2851 : /// The nonlinear systems
2852 : std::vector<std::shared_ptr<NonlinearSystemBase>> _nl;
2853 :
2854 : /// Map from nonlinear system name to number
2855 : std::map<NonlinearSystemName, unsigned int> _nl_sys_name_to_num;
2856 :
2857 : /// The current nonlinear system that we are solving
2858 : NonlinearSystemBase * _current_nl_sys;
2859 :
2860 : /// The current solver system
2861 : SolverSystem * _current_solver_sys;
2862 :
2863 : /// Combined container to base pointer of every solver system
2864 : std::vector<std::shared_ptr<SolverSystem>> _solver_systems;
2865 :
2866 : /// Map connecting variable names with their respective solver systems
2867 : std::map<SolverVariableName, unsigned int> _solver_var_to_sys_num;
2868 :
2869 : /// Map connecting solver system names with their respective systems
2870 : std::map<SolverSystemName, unsigned int> _solver_sys_name_to_num;
2871 :
2872 : /// The union of nonlinear and linear system names
2873 : std::vector<SolverSystemName> _solver_sys_names;
2874 :
2875 : /// The auxiliary system
2876 : std::shared_ptr<AuxiliarySystem> _aux;
2877 :
2878 : Moose::CouplingType _coupling; ///< Type of variable coupling
2879 : std::vector<std::unique_ptr<libMesh::CouplingMatrix>> _cm; ///< Coupling matrix for variables.
2880 :
2881 : #ifdef MOOSE_KOKKOS_ENABLED
2882 : Moose::Kokkos::Array<Moose::Kokkos::System> _kokkos_systems;
2883 : #endif
2884 :
2885 : /// Dimension of the subspace spanned by the vectors with a given prefix
2886 : std::map<std::string, unsigned int> _subspace_dim;
2887 :
2888 : /// The Assembly objects. The first index corresponds to the thread ID and the second index
2889 : /// corresponds to the nonlinear system number
2890 : std::vector<std::vector<std::unique_ptr<Assembly>>> _assembly;
2891 :
2892 : #ifdef MOOSE_KOKKOS_ENABLED
2893 : Moose::Kokkos::Assembly _kokkos_assembly;
2894 : #endif
2895 :
2896 : /// Warehouse to store mesh divisions
2897 : /// NOTE: this could probably be moved to the MooseMesh instead of the Problem
2898 : /// Time (and people's uses) will tell where this fits best
2899 : MooseObjectWarehouse<MeshDivision> _mesh_divisions;
2900 :
2901 : /// functions
2902 : MooseObjectWarehouse<Function> _functions;
2903 :
2904 : /// convergence warehouse
2905 : MooseObjectWarehouse<Convergence> _convergences;
2906 :
2907 : /// nonlocal kernels
2908 : MooseObjectWarehouse<KernelBase> _nonlocal_kernels;
2909 :
2910 : /// nonlocal integrated_bcs
2911 : MooseObjectWarehouse<IntegratedBCBase> _nonlocal_integrated_bcs;
2912 :
2913 : ///@{
2914 : /// Initial condition storage
2915 : InitialConditionWarehouse _ics;
2916 : FVInitialConditionWarehouse _fv_ics;
2917 : ScalarInitialConditionWarehouse _scalar_ics; // use base b/c of setup methods
2918 : ///@}
2919 :
2920 : // material properties
2921 : MaterialPropertyRegistry _material_prop_registry;
2922 : MaterialPropertyStorage & _material_props;
2923 : MaterialPropertyStorage & _bnd_material_props;
2924 : MaterialPropertyStorage & _neighbor_material_props;
2925 :
2926 : #ifdef MOOSE_KOKKOS_ENABLED
2927 : Moose::Kokkos::MaterialPropertyStorage & _kokkos_material_props;
2928 : Moose::Kokkos::MaterialPropertyStorage & _kokkos_bnd_material_props;
2929 : Moose::Kokkos::MaterialPropertyStorage & _kokkos_neighbor_material_props;
2930 : #endif
2931 : ///@{
2932 : // Material Warehouses
2933 : MaterialWarehouse _materials; // regular materials
2934 : MaterialWarehouse _interface_materials; // interface materials
2935 : MaterialWarehouse _discrete_materials; // Materials that the user must compute
2936 : MaterialWarehouse _all_materials; // All materials for error checking and MaterialData storage
2937 :
2938 : #ifdef MOOSE_KOKKOS_ENABLED
2939 : MaterialWarehouse _kokkos_materials; // Kokkos materials
2940 : #endif
2941 : ///@}
2942 :
2943 : ///@{
2944 : // Indicator Warehouses
2945 : MooseObjectWarehouse<Indicator> _indicators;
2946 : MooseObjectWarehouse<InternalSideIndicatorBase> _internal_side_indicators;
2947 : ///@}
2948 :
2949 : // Marker Warehouse
2950 : MooseObjectWarehouse<Marker> _markers;
2951 :
2952 : // Helper class to access Reporter object values
2953 : ReporterData _reporter_data;
2954 :
2955 : // TODO: delete this after apps have been updated to not call getUserObjects
2956 : ExecuteMooseObjectWarehouse<UserObject> _all_user_objects;
2957 :
2958 : /// MultiApp Warehouse
2959 : ExecuteMooseObjectWarehouse<MultiApp> _multi_apps;
2960 :
2961 : /// Storage for TransientMultiApps (only needed for calling 'computeDT')
2962 : ExecuteMooseObjectWarehouse<TransientMultiApp> _transient_multi_apps;
2963 :
2964 : /// Normal Transfers
2965 : ExecuteMooseObjectWarehouse<Transfer> _transfers;
2966 :
2967 : /// Transfers executed just before MultiApps to transfer data to them
2968 : ExecuteMooseObjectWarehouse<Transfer> _to_multi_app_transfers;
2969 :
2970 : /// Transfers executed just after MultiApps to transfer data from them
2971 : ExecuteMooseObjectWarehouse<Transfer> _from_multi_app_transfers;
2972 :
2973 : /// Transfers executed just before MultiApps to transfer data between them
2974 : ExecuteMooseObjectWarehouse<Transfer> _between_multi_app_transfers;
2975 :
2976 : /// A map of objects that consume random numbers
2977 : std::map<std::string, std::unique_ptr<RandomData>> _random_data_objects;
2978 :
2979 : /// Cache for calculating materials on side
2980 : std::vector<std::unordered_map<SubdomainID, bool>> _block_mat_side_cache;
2981 :
2982 : /// Cache for calculating materials on side
2983 : std::vector<std::unordered_map<BoundaryID, bool>> _bnd_mat_side_cache;
2984 :
2985 : /// Cache for calculating materials on interface
2986 : std::vector<std::unordered_map<BoundaryID, bool>> _interface_mat_side_cache;
2987 :
2988 : /// Objects to be notified when the mesh changes
2989 : std::vector<MeshChangedInterface *> _notify_when_mesh_changes;
2990 :
2991 : /// Objects to be notified when the mesh displaces
2992 : std::vector<MeshDisplacedInterface *> _notify_when_mesh_displaces;
2993 :
2994 : /// Helper to check for duplicate variable names across systems or within a single system
2995 : bool duplicateVariableCheck(const std::string & var_name,
2996 : const libMesh::FEType & type,
2997 : bool is_aux,
2998 : const std::set<SubdomainID> * const active_subdomains);
2999 :
3000 : void computeUserObjectsInternal(const ExecFlagType & type,
3001 : const Moose::AuxGroup & group,
3002 : TheWarehouse::Query & query);
3003 :
3004 : /// Verify that SECOND order mesh uses SECOND order displacements.
3005 : void checkDisplacementOrders();
3006 :
3007 : void checkUserObjects();
3008 :
3009 : /**
3010 : * Helper method for checking Material object dependency.
3011 : *
3012 : * @see checkProblemIntegrity
3013 : */
3014 : void checkDependMaterialsHelper(
3015 : const std::map<SubdomainID, std::vector<std::shared_ptr<MaterialBase>>> & materials_map);
3016 :
3017 : /// Verify that there are no element type/coordinate type conflicts
3018 : void checkCoordinateSystems();
3019 :
3020 : /**
3021 : * Call when it is possible that the needs for ghosted elements has changed.
3022 : * @param mortar_changed Whether an update of mortar data has been requested since the last
3023 : * EquationSystems (re)initialization
3024 : */
3025 : void reinitBecauseOfGhostingOrNewGeomObjects(bool mortar_changed = false);
3026 :
3027 : /**
3028 : * Helper for setting the "_subproblem" and "_sys" parameters in addObject() and
3029 : * in addUserObject().
3030 : *
3031 : * This is needed due to header includes/forward declaration issues
3032 : */
3033 : void addObjectParamsHelper(InputParameters & params,
3034 : const std::string & object_name,
3035 : const std::string & var_param_name = "variable");
3036 :
3037 : #ifdef LIBMESH_ENABLE_AMR
3038 : Adaptivity _adaptivity;
3039 : unsigned int _cycles_completed;
3040 : #endif
3041 :
3042 : /// Pointer to XFEM controller
3043 : std::shared_ptr<XFEMInterface> _xfem;
3044 :
3045 : // Displaced mesh /////
3046 : MooseMesh * _displaced_mesh;
3047 : std::shared_ptr<DisplacedProblem> _displaced_problem;
3048 : GeometricSearchData _geometric_search_data;
3049 : std::unique_ptr<MortarInterfaceWarehouse> _mortar_data;
3050 :
3051 : /// Whether to call DisplacedProblem::reinitElem when this->reinitElem is called
3052 : bool _reinit_displaced_elem;
3053 : /// Whether to call DisplacedProblem::reinitElemFace when this->reinitElemFace is called
3054 : bool _reinit_displaced_face;
3055 : /// Whether to call DisplacedProblem::reinitNeighbor when this->reinitNeighbor is called
3056 : bool _reinit_displaced_neighbor;
3057 :
3058 : /// whether input file has been written
3059 : bool _input_file_saved;
3060 :
3061 : /// Whether or not this system has any Dampers associated with it.
3062 : bool _has_dampers;
3063 :
3064 : /// Whether or not this system has any Constraints.
3065 : bool _has_constraints;
3066 :
3067 : /// If or not to resuse the base vector for matrix-free calculation
3068 : bool _snesmf_reuse_base;
3069 :
3070 : /// If or not skip 'exception and stop solve'
3071 : bool _skip_exception_check;
3072 :
3073 : /// If or not _snesmf_reuse_base is set by user
3074 : bool _snesmf_reuse_base_set_by_user;
3075 :
3076 : /// Whether nor not stateful materials have been initialized
3077 : bool _has_initialized_stateful;
3078 :
3079 : /// true if the Jacobian is constant
3080 : bool _const_jacobian;
3081 :
3082 : /// Indicates if the Jacobian was computed
3083 : bool _has_jacobian;
3084 :
3085 : /// Indicates that we need to compute variable values for previous Newton iteration
3086 : bool _needs_old_newton_iter;
3087 :
3088 : /// Indicates we need to save the previous NL iteration variable values
3089 : bool _previous_nl_solution_required;
3090 :
3091 : /// Indicates if nonlocal coupling is required/exists
3092 : bool _has_nonlocal_coupling;
3093 : bool _calculate_jacobian_in_uo;
3094 :
3095 : std::vector<std::vector<const MooseVariableFEBase *>> _uo_jacobian_moose_vars;
3096 :
3097 : /// Whether there are active material properties on each thread
3098 : std::vector<unsigned char> _has_active_material_properties;
3099 :
3100 : std::vector<SolverParams> _solver_params;
3101 :
3102 : /// Determines whether and which subdomains are to be checked to ensure that they have an active kernel
3103 : CoverageCheckMode _kernel_coverage_check;
3104 : std::vector<SubdomainName> _kernel_coverage_blocks;
3105 :
3106 : /// whether to perform checking of boundary restricted nodal object variable dependencies,
3107 : /// e.g. whether the variable dependencies are defined on the selected boundaries
3108 : const bool _boundary_restricted_node_integrity_check;
3109 :
3110 : /// whether to perform checking of boundary restricted elemental object variable dependencies,
3111 : /// e.g. whether the variable dependencies are defined on the selected boundaries
3112 : const bool _boundary_restricted_elem_integrity_check;
3113 :
3114 : /// Determines whether and which subdomains are to be checked to ensure that they have an active material
3115 : CoverageCheckMode _material_coverage_check;
3116 : std::vector<SubdomainName> _material_coverage_blocks;
3117 :
3118 : /// Whether to check overlapping Dirichlet and Flux BCs and/or multiple DirichletBCs per sideset
3119 : bool _fv_bcs_integrity_check;
3120 :
3121 : /// Determines whether a check to verify material dependencies on every subdomain
3122 : const bool _material_dependency_check;
3123 :
3124 : /// Whether or not checking the state of uo/aux evaluation
3125 : const bool _uo_aux_state_check;
3126 :
3127 : /// Maximum number of quadrature points used in the problem
3128 : unsigned int _max_qps;
3129 :
3130 : /// Maximum scalar variable order
3131 : libMesh::Order _max_scalar_order;
3132 :
3133 : /// Indicates whether or not this executioner has a time integrator (during setup)
3134 : bool _has_time_integrator;
3135 :
3136 : /// Whether or not an exception has occurred
3137 : bool _has_exception;
3138 :
3139 : /// Whether or not information about how many transfers have completed is printed
3140 : bool _parallel_barrier_messaging;
3141 :
3142 : /// Whether or not to be verbose during setup
3143 : MooseEnum _verbose_setup;
3144 :
3145 : /// Whether or not to be verbose with multiapps
3146 : bool _verbose_multiapps;
3147 :
3148 : /// Whether or not to be verbose on solution restoration post a failed time step
3149 : bool _verbose_restore;
3150 :
3151 : /// The error message to go with an exception
3152 : std::string _exception_message;
3153 :
3154 : /// Current execute_on flag
3155 : ExecFlagType _current_execute_on_flag;
3156 :
3157 : /// The control logic warehouse
3158 : ExecuteMooseObjectWarehouse<Control> _control_warehouse;
3159 :
3160 : /// PETSc option storage
3161 : Moose::PetscSupport::PetscOptions _petsc_options;
3162 : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
3163 : PetscOptions _petsc_option_data_base;
3164 : #endif
3165 :
3166 : /// If or not PETSc options have been added to database
3167 : bool _is_petsc_options_inserted;
3168 :
3169 : std::shared_ptr<LineSearch> _line_search;
3170 :
3171 : std::unique_ptr<libMesh::ConstElemRange> _evaluable_local_elem_range;
3172 : std::unique_ptr<libMesh::ConstElemRange> _nl_evaluable_local_elem_range;
3173 : std::unique_ptr<libMesh::ConstElemRange> _aux_evaluable_local_elem_range;
3174 :
3175 : std::unique_ptr<libMesh::ConstElemRange> _current_algebraic_elem_range;
3176 : std::unique_ptr<libMesh::ConstNodeRange> _current_algebraic_node_range;
3177 : std::unique_ptr<ConstBndNodeRange> _current_algebraic_bnd_node_range;
3178 :
3179 : /// Automatic differentiaion (AD) flag which indicates whether any consumer has
3180 : /// requested an AD material property or whether any suppier has declared an AD material property
3181 : bool _using_ad_mat_props;
3182 :
3183 : // loop state during projection of initial conditions
3184 : unsigned short _current_ic_state;
3185 :
3186 : /// Whether to assemble matrices using hash tables instead of preallocating matrix memory. This
3187 : /// can be a good option if the sparsity pattern changes throughout the course of the simulation
3188 : const bool _use_hash_table_matrix_assembly;
3189 :
3190 : private:
3191 : /**
3192 : * Handle exceptions. Note that the result of this call will be a thrown MooseException. The
3193 : * caller of this method must determine how to handle the thrown exception
3194 : */
3195 : void handleException(const std::string & calling_method);
3196 :
3197 : /**
3198 : * Helper for getting mortar objects corresponding to primary boundary ID, secondary boundary ID,
3199 : * and displaced parameters, given some initial set
3200 : */
3201 : std::vector<MortarUserObject *>
3202 : getMortarUserObjects(BoundaryID primary_boundary_id,
3203 : BoundaryID secondary_boundary_id,
3204 : bool displaced,
3205 : const std::vector<MortarUserObject *> & mortar_uo_superset);
3206 :
3207 : /**
3208 : * Helper for getting mortar objects corresponding to primary boundary ID, secondary boundary ID,
3209 : * and displaced parameters from the entire active mortar user object set
3210 : */
3211 : std::vector<MortarUserObject *> getMortarUserObjects(BoundaryID primary_boundary_id,
3212 : BoundaryID secondary_boundary_id,
3213 : bool displaced);
3214 :
3215 : /**
3216 : * Determine what solver system the provided variable name lies in
3217 : * @param var_name The name of the variable we are doing solver system lookups for
3218 : * @param error_if_not_found Whether to error if the variable name isn't found in any of the
3219 : * solver systems
3220 : * @return A pair in which the first member indicates whether the variable was found in the
3221 : * solver systems and the second member indicates the solver system number in which the
3222 : * variable was found (or an invalid unsigned integer if not found)
3223 : */
3224 : virtual std::pair<bool, unsigned int>
3225 : determineSolverSystem(const std::string & var_name,
3226 : bool error_if_not_found = false) const override;
3227 :
3228 : /**
3229 : * Checks if the variable of the initial condition is getting restarted and errors for specific
3230 : * cases
3231 : * @param ic_name The name of the initial condition
3232 : * @param var_name The name of the variable
3233 : */
3234 : void checkICRestartError(const std::string & ic_name,
3235 : const std::string & name,
3236 : const VariableName & var_name);
3237 :
3238 : /*
3239 : * Test if stateful property redistribution is expected to be
3240 : * necessary, and set it up if so.
3241 : */
3242 : void addAnyRedistributers();
3243 :
3244 : void updateMaxQps();
3245 :
3246 : void joinAndFinalize(TheWarehouse::Query query, bool isgen = false);
3247 :
3248 : /**
3249 : * Reset state of this object in preparation for the next evaluation.
3250 : */
3251 : virtual void resetState();
3252 :
3253 : // Parameters handling Jacobian sparsity pattern behavior
3254 : /// Whether to error when the Jacobian is re-allocated, usually because the sparsity pattern changed
3255 : bool _error_on_jacobian_nonzero_reallocation;
3256 : /// Whether we should restore the original nonzero pattern for every Jacobian evaluation. This
3257 : /// option is useful if the sparsity pattern is constantly changing and you are using hash table
3258 : /// assembly or if you wish to continually restore the matrix to the originally preallocated
3259 : /// sparsity pattern computed by relationship managers.
3260 : const bool _restore_original_nonzero_pattern;
3261 : /// Whether to ignore zeros in the Jacobian, thereby leading to a reduced sparsity pattern
3262 : bool _ignore_zeros_in_jacobian;
3263 : /// Whether to preserve the system matrix / Jacobian sparsity pattern, using 0-valued entries usually
3264 : bool _preserve_matrix_sparsity_pattern;
3265 :
3266 : const bool _force_restart;
3267 : const bool _allow_ics_during_restart;
3268 : const bool _skip_nl_system_check;
3269 : bool _fail_next_system_convergence_check;
3270 : const bool _allow_invalid_solution;
3271 : const bool _show_invalid_solution_console;
3272 : const bool & _immediately_print_invalid_solution;
3273 :
3274 : /// At or beyond initialSteup stage
3275 : bool _started_initial_setup;
3276 :
3277 : /// Whether the problem has dgkernels or interface kernels
3278 : bool _has_internal_edge_residual_objects;
3279 :
3280 : /// Whether solution time derivative needs to be stored
3281 : bool _u_dot_requested;
3282 :
3283 : /// Whether solution second time derivative needs to be stored
3284 : bool _u_dotdot_requested;
3285 :
3286 : /// Whether old solution time derivative needs to be stored
3287 : bool _u_dot_old_requested;
3288 :
3289 : /// Whether old solution second time derivative needs to be stored
3290 : bool _u_dotdot_old_requested;
3291 :
3292 : friend class AuxiliarySystem;
3293 : friend class NonlinearSystemBase;
3294 : friend class MooseEigenSystem;
3295 : friend class Resurrector;
3296 : friend class Restartable;
3297 : friend class DisplacedProblem;
3298 :
3299 : /// Whether the simulation requires mortar coupling
3300 : bool _has_mortar;
3301 :
3302 : /// Number of steps in a grid sequence
3303 : unsigned int _num_grid_steps;
3304 :
3305 : /// Whether to trust the user coupling matrix no matter what. See
3306 : /// https://github.com/idaholab/moose/issues/16395 for detailed background
3307 : bool _trust_user_coupling_matrix = false;
3308 :
3309 : /// Flag used to indicate whether we are computing the scaling Jacobian
3310 : bool _computing_scaling_jacobian = false;
3311 :
3312 : /// Flag used to indicate whether we are computing the scaling Residual
3313 : bool _computing_scaling_residual = false;
3314 :
3315 : /// Flag used to indicate whether we are doing the uo/aux state check in execute
3316 : bool _checking_uo_aux_state = false;
3317 :
3318 : /// When to print the execution of loops
3319 : ExecFlagEnum _print_execution_on;
3320 :
3321 : /// Whether to identify variable groups in nonlinear systems. This affects dof ordering
3322 : const bool _identify_variable_groups_in_nl;
3323 :
3324 : /// A data member to store the residual vector tag(s) passed into \p computeResidualTag(s). This
3325 : /// data member will be used when APIs like \p cacheResidual, \p addCachedResiduals, etc. are
3326 : /// called
3327 : std::vector<VectorTag> _current_residual_vector_tags;
3328 :
3329 : /// Whether we are performing some calculations with finite volume discretizations
3330 : bool _have_fv = false;
3331 :
3332 : /// If we catch an exception during residual/Jacobian evaluaton for which we don't have specific
3333 : /// handling, immediately error instead of allowing the time step to be cut
3334 : const bool _regard_general_exceptions_as_errors;
3335 :
3336 : /// nonlocal coupling matrix
3337 : std::vector<libMesh::CouplingMatrix> _nonlocal_cm;
3338 :
3339 : /// nonlocal coupling requirement flag
3340 : bool _requires_nonlocal_coupling;
3341 :
3342 : #ifdef MOOSE_KOKKOS_ENABLED
3343 : /// Whether we have any Kokkos objects
3344 : bool _has_kokkos_objects = false;
3345 :
3346 : /// Whether we have any Kokkos residual objects
3347 : bool _has_kokkos_residual_objects = false;
3348 : #endif
3349 :
3350 : friend void Moose::PetscSupport::setSinglePetscOption(const std::string & name,
3351 : const std::string & value,
3352 : FEProblemBase * const problem);
3353 : };
3354 :
3355 : using FVProblemBase = FEProblemBase;
3356 :
3357 : template <typename T>
3358 : void
3359 1748 : FEProblemBase::allowOutput(bool state)
3360 : {
3361 1748 : _app.getOutputWarehouse().allowOutput<T>(state);
3362 1748 : }
3363 :
3364 : template <typename T>
3365 : void
3366 55 : FEProblemBase::objectSetupHelper(const std::vector<T *> & objects, const ExecFlagType & exec_flag)
3367 : {
3368 55 : if (exec_flag == EXEC_INITIAL)
3369 : {
3370 0 : for (T * obj_ptr : objects)
3371 0 : obj_ptr->initialSetup();
3372 : }
3373 :
3374 55 : else if (exec_flag == EXEC_TIMESTEP_BEGIN)
3375 : {
3376 0 : for (const auto obj_ptr : objects)
3377 0 : obj_ptr->timestepSetup();
3378 : }
3379 55 : else if (exec_flag == EXEC_SUBDOMAIN)
3380 : {
3381 0 : for (const auto obj_ptr : objects)
3382 0 : obj_ptr->subdomainSetup();
3383 : }
3384 :
3385 55 : else if (exec_flag == EXEC_NONLINEAR)
3386 : {
3387 0 : for (const auto obj_ptr : objects)
3388 0 : obj_ptr->jacobianSetup();
3389 : }
3390 :
3391 55 : else if (exec_flag == EXEC_LINEAR)
3392 : {
3393 0 : for (const auto obj_ptr : objects)
3394 0 : obj_ptr->residualSetup();
3395 : }
3396 55 : }
3397 :
3398 : template <typename T>
3399 : void
3400 55 : FEProblemBase::objectExecuteHelper(const std::vector<T *> & objects)
3401 : {
3402 78 : for (T * obj_ptr : objects)
3403 55 : obj_ptr->execute();
3404 23 : }
3405 :
3406 : template <typename T>
3407 : std::vector<std::shared_ptr<T>>
3408 55707 : FEProblemBase::addObject(const std::string & type,
3409 : const std::string & name,
3410 : InputParameters & parameters,
3411 : const bool threaded,
3412 : const std::string & var_param_name)
3413 : {
3414 : parallel_object_only();
3415 :
3416 55707 : logAdd(MooseUtils::prettyCppType<T>(), name, type, parameters);
3417 : // Add the _subproblem and _sys parameters depending on use_displaced_mesh
3418 55707 : addObjectParamsHelper(parameters, name, var_param_name);
3419 :
3420 55707 : const auto n_threads = threaded ? libMesh::n_threads() : 1;
3421 55707 : std::vector<std::shared_ptr<T>> objects(n_threads);
3422 112266 : for (THREAD_ID tid = 0; tid < n_threads; ++tid)
3423 : {
3424 56607 : std::shared_ptr<T> obj = _factory.create<T>(type, name, parameters, tid);
3425 56559 : theWarehouse().add(obj);
3426 56559 : objects[tid] = std::move(obj);
3427 : }
3428 :
3429 55659 : return objects;
3430 4 : }
3431 :
3432 : inline NonlinearSystemBase &
3433 6667941 : FEProblemBase::getNonlinearSystemBase(const unsigned int sys_num)
3434 : {
3435 : mooseAssert(sys_num < _nl.size(), "System number greater than the number of nonlinear systems");
3436 6667941 : return *_nl[sys_num];
3437 : }
3438 :
3439 : inline const NonlinearSystemBase &
3440 581 : FEProblemBase::getNonlinearSystemBase(const unsigned int sys_num) const
3441 : {
3442 : mooseAssert(sys_num < _nl.size(), "System number greater than the number of nonlinear systems");
3443 581 : return *_nl[sys_num];
3444 : }
3445 :
3446 : inline SolverSystem &
3447 4497987 : FEProblemBase::getSolverSystem(const unsigned int sys_num)
3448 : {
3449 : mooseAssert(sys_num < _solver_systems.size(),
3450 : "System number greater than the number of solver systems");
3451 4497987 : return *_solver_systems[sys_num];
3452 : }
3453 :
3454 : inline const SolverSystem &
3455 : FEProblemBase::getSolverSystem(const unsigned int sys_num) const
3456 : {
3457 : mooseAssert(sys_num < _solver_systems.size(),
3458 : "System number greater than the number of solver systems");
3459 : return *_solver_systems[sys_num];
3460 : }
3461 :
3462 : inline NonlinearSystemBase &
3463 9945387 : FEProblemBase::currentNonlinearSystem()
3464 : {
3465 : mooseAssert(_current_nl_sys, "The nonlinear system is not currently set");
3466 9945387 : return *_current_nl_sys;
3467 : }
3468 :
3469 : inline const NonlinearSystemBase &
3470 594817515 : FEProblemBase::currentNonlinearSystem() const
3471 : {
3472 : mooseAssert(_current_nl_sys, "The nonlinear system is not currently set");
3473 594817515 : return *_current_nl_sys;
3474 : }
3475 :
3476 : inline LinearSystem &
3477 77057 : FEProblemBase::getLinearSystem(const unsigned int sys_num)
3478 : {
3479 : mooseAssert(sys_num < _linear_systems.size(),
3480 : "System number greater than the number of linear systems");
3481 77057 : return *_linear_systems[sys_num];
3482 : }
3483 :
3484 : inline const LinearSystem &
3485 : FEProblemBase::getLinearSystem(const unsigned int sys_num) const
3486 : {
3487 : mooseAssert(sys_num < _linear_systems.size(),
3488 : "System number greater than the number of linear systems");
3489 : return *_linear_systems[sys_num];
3490 : }
3491 :
3492 : inline LinearSystem &
3493 2634 : FEProblemBase::currentLinearSystem()
3494 : {
3495 : mooseAssert(_current_linear_sys, "The linear system is not currently set");
3496 2634 : return *_current_linear_sys;
3497 : }
3498 :
3499 : inline const LinearSystem &
3500 0 : FEProblemBase::currentLinearSystem() const
3501 : {
3502 : mooseAssert(_current_linear_sys, "The linear system is not currently set");
3503 0 : return *_current_linear_sys;
3504 : }
3505 :
3506 : inline Assembly &
3507 705424393 : FEProblemBase::assembly(const THREAD_ID tid, const unsigned int sys_num)
3508 : {
3509 : mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
3510 : mooseAssert(sys_num < _assembly[tid].size(),
3511 : "System number larger than the assembly container size");
3512 705424393 : return *_assembly[tid][sys_num];
3513 : }
3514 :
3515 : inline const Assembly &
3516 552796 : FEProblemBase::assembly(const THREAD_ID tid, const unsigned int sys_num) const
3517 : {
3518 : mooseAssert(tid < _assembly.size(), "Assembly objects not initialized");
3519 : mooseAssert(sys_num < _assembly[tid].size(),
3520 : "System number larger than the assembly container size");
3521 552796 : return *_assembly[tid][sys_num];
3522 : }
3523 :
3524 : inline const libMesh::CouplingMatrix *
3525 2966 : FEProblemBase::couplingMatrix(const unsigned int i) const
3526 : {
3527 2966 : return _cm[i].get();
3528 : }
3529 :
3530 : inline void
3531 : FEProblemBase::fvBCsIntegrityCheck(const bool fv_bcs_integrity_check)
3532 : {
3533 : if (!_fv_bcs_integrity_check)
3534 : // the user has requested that we don't check integrity so we will honor that
3535 : return;
3536 :
3537 : _fv_bcs_integrity_check = fv_bcs_integrity_check;
3538 : }
3539 :
3540 : inline const std::vector<VectorTag> &
3541 478111640 : FEProblemBase::currentResidualVectorTags() const
3542 : {
3543 478111640 : return _current_residual_vector_tags;
3544 : }
3545 :
3546 : inline void
3547 3341763 : FEProblemBase::setCurrentResidualVectorTags(const std::set<TagID> & vector_tags)
3548 : {
3549 3341763 : _current_residual_vector_tags = getVectorTags(vector_tags);
3550 3341763 : }
3551 :
3552 : inline void
3553 3876195 : FEProblemBase::clearCurrentResidualVectorTags()
3554 : {
3555 3876195 : _current_residual_vector_tags.clear();
3556 3876195 : }
|