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