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