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