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