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