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 : #include <map>
13 : #include <set>
14 : #include <vector>
15 :
16 : #include "DataIO.h"
17 : #include "MooseTypes.h"
18 : #include "VariableWarehouse.h"
19 : #include "InputParameters.h"
20 : #include "MooseVariableBase.h"
21 : #include "ConsoleStreamInterface.h"
22 : // libMesh
23 : #include "libmesh/exodusII_io.h"
24 : #include "libmesh/parallel_object.h"
25 : #include "libmesh/numeric_vector.h"
26 : #include "libmesh/sparse_matrix.h"
27 :
28 : // Forward declarations
29 : class Factory;
30 : class MooseApp;
31 : class MooseVariableFieldBase;
32 : template <typename>
33 : class MooseVariableFE;
34 : typedef MooseVariableFE<Real> MooseVariable;
35 : typedef MooseVariableFE<VectorValue<Real>> VectorMooseVariable;
36 : class MooseMesh;
37 : class SubProblem;
38 : class SystemBase;
39 : class TimeIntegrator;
40 : class InputParameters;
41 : class FEProblemBase;
42 :
43 : // libMesh forward declarations
44 : namespace libMesh
45 : {
46 : class System;
47 : class DofMap;
48 : class FEType;
49 : }
50 :
51 : /**
52 : * ///< Type of coordinate system
53 : */
54 : void extraSendList(std::vector<dof_id_type> & send_list, void * context);
55 :
56 : /**
57 : * Free function used for a libMesh callback
58 : */
59 : void extraSparsity(libMesh::SparsityPattern::Graph & sparsity,
60 : std::vector<dof_id_type> & n_nz,
61 : std::vector<dof_id_type> & n_oz,
62 : void * context);
63 :
64 : /**
65 : * Information about variables that will be copied
66 : */
67 : struct VarCopyInfo
68 : {
69 626 : VarCopyInfo(const std::string & dest_name,
70 : const std::string & source_name,
71 : const std::string & timestep)
72 626 : : _dest_name(dest_name), _source_name(source_name), _timestep(timestep)
73 : {
74 626 : }
75 :
76 : std::string _dest_name;
77 : std::string _source_name;
78 : std::string _timestep;
79 : };
80 :
81 : /**
82 : * Base class for a system (of equations)
83 : *
84 : */
85 : class SystemBase : public libMesh::ParallelObject, public ConsoleStreamInterface
86 :
87 : {
88 : public:
89 : SystemBase(SubProblem & subproblem,
90 : FEProblemBase & fe_problem,
91 : const std::string & name,
92 : Moose::VarKindType var_kind);
93 121414 : virtual ~SystemBase() {}
94 :
95 : /**
96 : * Gets the number of this system
97 : * @return The number of this system
98 : */
99 : unsigned int number() const;
100 41557426 : MooseMesh & mesh() { return _mesh; }
101 : const MooseMesh & mesh() const { return _mesh; }
102 93905062 : SubProblem & subproblem() { return _subproblem; }
103 1394692 : const SubProblem & subproblem() const { return _subproblem; }
104 57819 : FEProblemBase & feProblem() { return _fe_problem; }
105 43776 : const FEProblemBase & feProblem() const { return _fe_problem; }
106 :
107 : /**
108 : * Applies scaling factors to the system's variables
109 : * @param inverse_scaling_factors A vector containing the inverse of each variable's scaling
110 : * factor, e.g. 1 / scaling_factor
111 : */
112 : void applyScalingFactors(const std::vector<Real> & inverse_scaling_factors);
113 :
114 : /**
115 : * Whether we are computing an initial Jacobian for automatic variable scaling
116 : */
117 : bool computingScalingJacobian() const;
118 :
119 : /**
120 : * Getter for whether we are performing automatic scaling
121 : * @return whether we are performing automatic scaling
122 : */
123 12935 : bool automaticScaling() const { return _automatic_scaling; }
124 :
125 : /**
126 : * Setter for whether we are performing automatic scaling
127 : * @param automatic_scaling A boolean representing whether we are performing automatic scaling
128 : */
129 62989 : void automaticScaling(bool automatic_scaling) { _automatic_scaling = automatic_scaling; }
130 :
131 : /**
132 : * Sets the verbose flag
133 : * @param[in] verbose Verbose flag
134 : */
135 60309 : void setVerboseFlag(const bool & verbose) { _verbose = verbose; }
136 :
137 : /**
138 : * Gets writeable reference to the dof map
139 : */
140 : virtual libMesh::DofMap & dofMap();
141 :
142 : /**
143 : * Gets const reference to the dof map
144 : */
145 : virtual const libMesh::DofMap & dofMap() const;
146 :
147 : /**
148 : * Get the reference to the libMesh system
149 : */
150 : virtual libMesh::System & system() = 0;
151 : virtual const libMesh::System & system() const = 0;
152 :
153 : /**
154 : * This is called prior to the libMesh system has been init'd. MOOSE system wrappers can use this
155 : * method to add vectors and matrices to the libMesh system
156 : */
157 124053 : virtual void preInit() {}
158 :
159 : /*
160 : * This is called after the libMesh system has been init'd. This can be used to initialize MOOSE
161 : * system data that relies on the libMesh system data already being initialized
162 : */
163 124053 : virtual void postInit() {}
164 :
165 : /**
166 : * Reinitialize the system when the degrees of freedom in this system have changed. This is called
167 : * after the libMesh system has been reinit'd
168 : */
169 4638 : virtual void reinit() {}
170 :
171 : /**
172 : * Called only once, just before the solve begins so objects can do some precalculations
173 : */
174 0 : virtual void initializeObjects() {}
175 :
176 : /**
177 : * Update the system (doing libMesh magic)
178 : */
179 : void update();
180 :
181 : /**
182 : * Solve the system (using libMesh magic)
183 : */
184 : virtual void solve();
185 :
186 : virtual void copyOldSolutions();
187 : virtual void copyPreviousNonlinearSolutions();
188 : virtual void copyPreviousFixedPointSolutions();
189 : virtual void restoreSolutions();
190 :
191 : /**
192 : * The solution vector that is currently being operated on.
193 : * This is typically a ghosted vector that comes in from the Nonlinear solver.
194 : */
195 : virtual const NumericVector<Number> * const & currentSolution() const = 0;
196 :
197 54645780 : NumericVector<Number> & solution() { return solutionState(0); }
198 160905 : NumericVector<Number> & solutionOld() { return solutionState(1); }
199 11926 : NumericVector<Number> & solutionOlder() { return solutionState(2); }
200 89316 : const NumericVector<Number> & solution() const { return solutionState(0); }
201 97502 : const NumericVector<Number> & solutionOld() const { return solutionState(1); }
202 2148 : const NumericVector<Number> & solutionOlder() const { return solutionState(2); }
203 :
204 : virtual const NumericVector<Number> * solutionPreviousNewton() const;
205 : virtual NumericVector<Number> * solutionPreviousNewton();
206 :
207 : /**
208 : * Initializes the solution state.
209 : */
210 : virtual void initSolutionState();
211 :
212 : /**
213 : * Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
214 : *
215 : * If the state does not exist, it will be initialized in addition to any newer
216 : * states before it that have not been initialized.
217 : */
218 : virtual NumericVector<Number> &
219 : solutionState(const unsigned int state,
220 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time);
221 :
222 : /**
223 : * Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
224 : */
225 : virtual const NumericVector<Number> & solutionState(
226 : const unsigned int state,
227 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time) const;
228 :
229 : /**
230 : * Returns the parallel type of the given solution state
231 : */
232 : libMesh::ParallelType
233 : solutionStateParallelType(const unsigned int state,
234 : const Moose::SolutionIterationType iteration_type) const;
235 :
236 : /**
237 : * Registers that the solution state \p state is needed.
238 : */
239 : virtual void needSolutionState(
240 : const unsigned int state,
241 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time,
242 : libMesh::ParallelType parallel_type = GHOSTED);
243 :
244 : /**
245 : * Whether or not the system has the solution state (0 = current, 1 = old, 2 = older, etc).
246 : */
247 : virtual bool hasSolutionState(
248 : const unsigned int state,
249 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time) const;
250 :
251 : /**
252 : * Add u_dot, u_dotdot, u_dot_old and u_dotdot_old
253 : * vectors if requested by the time integrator
254 : */
255 : virtual void addDotVectors();
256 :
257 60187 : virtual std::vector<Number> & duDotDus() { return _du_dot_du; }
258 47939 : virtual Number & duDotDotDu() { return _du_dotdot_du; }
259 : virtual const Number & duDotDu(unsigned int var_num = 0) const;
260 464181 : virtual const Number & duDotDotDu() const { return _du_dotdot_du; }
261 :
262 317040453 : virtual NumericVector<Number> * solutionUDot() { return _u_dot; }
263 76176 : virtual NumericVector<Number> * solutionUDotDot() { return _u_dotdot; }
264 1250577 : virtual NumericVector<Number> * solutionUDotOld() { return _u_dot_old; }
265 1250577 : virtual NumericVector<Number> * solutionUDotDotOld() { return _u_dotdot_old; }
266 464181 : virtual const NumericVector<Number> * solutionUDot() const { return _u_dot; }
267 464181 : virtual const NumericVector<Number> * solutionUDotDot() const { return _u_dotdot; }
268 464181 : virtual const NumericVector<Number> * solutionUDotOld() const { return _u_dot_old; }
269 464181 : virtual const NumericVector<Number> * solutionUDotDotOld() const { return _u_dotdot_old; }
270 :
271 : virtual void saveOldSolutions();
272 : virtual void restoreOldSolutions();
273 :
274 : /**
275 : * Check if the named vector exists in the system.
276 : */
277 : bool hasVector(const std::string & tag_name) const;
278 :
279 : /**
280 : * Check if the tagged vector exists in the system.
281 : */
282 4672185277 : virtual bool hasVector(TagID tag_id) const
283 : {
284 4672185277 : return tag_id < _tagged_vectors.size() && _tagged_vectors[tag_id];
285 : }
286 :
287 : /**
288 : * Ideally, we should not need this API.
289 : * There exists a really bad API "addCachedResidualDirectly " in FEProblem and DisplacedProblem
290 : * This API should go away once addCachedResidualDirectly is removed in the future
291 : * Return Tag ID for Time
292 : */
293 0 : virtual TagID timeVectorTag() const { mooseError("Not implemented yet"); }
294 :
295 : /**
296 : * Return the Matrix Tag ID for System
297 : */
298 0 : virtual TagID systemMatrixTag() const { mooseError("Not implemented yet"); }
299 :
300 : /*
301 : * Return TagID for nontime
302 : */
303 0 : virtual TagID nonTimeVectorTag() const { mooseError("Not implemented yet"); }
304 :
305 : /*
306 : * Return TagID for nontime
307 : */
308 0 : virtual TagID residualVectorTag() const { mooseError("Not implemented yet"); }
309 :
310 : /**
311 : * Get the default vector tags associated with this system
312 : */
313 30615 : virtual std::set<TagID> defaultVectorTags() const
314 : {
315 91845 : return {timeVectorTag(), nonTimeVectorTag(), residualVectorTag()};
316 : }
317 : /**
318 : * Get the default matrix tags associted with this system
319 : */
320 11811 : virtual std::set<TagID> defaultMatrixTags() const { return {systemMatrixTag()}; }
321 :
322 : /**
323 : * Get a raw NumericVector by name
324 : */
325 : ///@{
326 : virtual NumericVector<Number> & getVector(const std::string & name);
327 : virtual const NumericVector<Number> & getVector(const std::string & name) const;
328 : ///@}
329 :
330 : /**
331 : * Get a raw NumericVector by tag
332 : */
333 : ///@{
334 : virtual NumericVector<Number> & getVector(TagID tag);
335 : virtual const NumericVector<Number> & getVector(TagID tag) const;
336 : ///@}
337 :
338 : /**
339 : * Associate a vector for a given tag
340 : */
341 : virtual void associateVectorToTag(NumericVector<Number> & vec, TagID tag);
342 :
343 : /**
344 : * Disassociate a given vector from a given tag
345 : */
346 : virtual void disassociateVectorFromTag(NumericVector<Number> & vec, TagID tag);
347 :
348 : /**
349 : * Disassociate any vector that is associated with a given tag
350 : */
351 : virtual void disassociateVectorFromTag(TagID tag);
352 :
353 : /**
354 : * Disassociate the vectors associated with the default vector tags of this system
355 : */
356 : virtual void disassociateDefaultVectorTags();
357 :
358 : /**
359 : * Check if the tagged matrix exists in the system.
360 : */
361 1895587181 : virtual bool hasMatrix(TagID tag) const
362 : {
363 1895587181 : return tag < _tagged_matrices.size() && _tagged_matrices[tag];
364 : }
365 :
366 : /**
367 : * Get a raw SparseMatrix
368 : */
369 : virtual libMesh::SparseMatrix<Number> & getMatrix(TagID tag);
370 :
371 : /**
372 : * Get a raw SparseMatrix
373 : */
374 : virtual const libMesh::SparseMatrix<Number> & getMatrix(TagID tag) const;
375 :
376 : /**
377 : * Make all existing matrices active
378 : */
379 : virtual void activateAllMatrixTags();
380 :
381 : /**
382 : * If or not a matrix tag is active
383 : */
384 : virtual bool matrixTagActive(TagID tag) const;
385 :
386 : /**
387 : * Make matrices inactive
388 : */
389 : virtual void deactivateAllMatrixTags();
390 :
391 : /**
392 : * Close all matrices associated the tags
393 : */
394 : void closeTaggedMatrices(const std::set<TagID> & tags);
395 :
396 : /**
397 : * flushes all matrices associated to tags. Flush assembles the matrix but doesn't shrink memory
398 : * allocation
399 : */
400 : void flushTaggedMatrices(const std::set<TagID> & tags);
401 :
402 : /**
403 : * Associate a matrix to a tag
404 : */
405 : virtual void associateMatrixToTag(libMesh::SparseMatrix<Number> & matrix, TagID tag);
406 :
407 : /**
408 : * Disassociate a matrix from a tag
409 : */
410 : virtual void disassociateMatrixFromTag(libMesh::SparseMatrix<Number> & matrix, TagID tag);
411 :
412 : /**
413 : * Disassociate any matrix that is associated with a given tag
414 : */
415 : virtual void disassociateMatrixFromTag(TagID tag);
416 :
417 : /**
418 : * Disassociate the matrices associated with the default matrix tags of this system
419 : */
420 : virtual void disassociateDefaultMatrixTags();
421 :
422 : /**
423 : * Returns a reference to a serialized version of the solution vector for this subproblem
424 : */
425 : virtual NumericVector<Number> & serializedSolution();
426 :
427 0 : virtual NumericVector<Number> & residualCopy()
428 : {
429 0 : mooseError("This system does not support getting a copy of the residual");
430 : }
431 0 : virtual NumericVector<Number> & residualGhosted()
432 : {
433 0 : mooseError("This system does not support getting a ghosted copy of the residual");
434 : }
435 :
436 : /**
437 : * Will modify the send_list to add all of the extra ghosted dofs for this system
438 : */
439 : virtual void augmentSendList(std::vector<dof_id_type> & send_list);
440 :
441 : /**
442 : * Will modify the sparsity pattern to add logical geometric connections
443 : */
444 : virtual void augmentSparsity(libMesh::SparsityPattern::Graph & sparsity,
445 : std::vector<dof_id_type> & n_nz,
446 : std::vector<dof_id_type> & n_oz) = 0;
447 :
448 : /**
449 : * Canonical method for adding a variable
450 : * @param var_type the type of the variable, e.g. MooseVariableScalar
451 : * @param var_name the variable name, e.g. 'u'
452 : * @param params the InputParameters from which to construct the variable
453 : */
454 : virtual void addVariable(const std::string & var_type,
455 : const std::string & var_name,
456 : InputParameters & parameters);
457 :
458 : /**
459 : * If a variable is an array variable
460 : */
461 : virtual bool isArrayVariable(const std::string & var_name) const;
462 :
463 : ///@{
464 : /**
465 : * Query a system for a variable
466 : *
467 : * @param var_name name of the variable
468 : * @return true if the variable exists
469 : */
470 : virtual bool hasVariable(const std::string & var_name) const;
471 : virtual bool hasScalarVariable(const std::string & var_name) const;
472 : ///@}
473 :
474 : virtual bool isScalarVariable(unsigned int var_name) const;
475 :
476 : /**
477 : * Gets a reference to a variable of with specified name
478 : *
479 : * @param tid Thread id
480 : * @param var_name variable name
481 : * @return reference the variable (class)
482 : */
483 : MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string & var_name) const;
484 :
485 : /**
486 : * Gets a reference to a variable with specified number
487 : *
488 : * @param tid Thread id
489 : * @param var_number libMesh variable number
490 : * @return reference the variable (class)
491 : */
492 : MooseVariableFieldBase & getVariable(THREAD_ID tid, unsigned int var_number) const;
493 :
494 : /**
495 : * Gets a reference to a variable of with specified name
496 : *
497 : * This excludes and cannot return finite volume variables.
498 : *
499 : * @param tid Thread id
500 : * @param var_name variable name
501 : * @return reference the variable (class)
502 : */
503 : template <typename T>
504 : MooseVariableFE<T> & getFieldVariable(THREAD_ID tid, const std::string & var_name);
505 :
506 : /**
507 : * Returns a field variable pointer - this includes finite volume variables.
508 : */
509 : template <typename T>
510 : MooseVariableField<T> & getActualFieldVariable(THREAD_ID tid, const std::string & var_name);
511 :
512 : /**
513 : * Gets a reference to a variable with specified number
514 : *
515 : * This excludes and cannot return finite volume variables.
516 : *
517 : * @param tid Thread id
518 : * @param var_number libMesh variable number
519 : * @return reference the variable (class)
520 : */
521 : template <typename T>
522 : MooseVariableFE<T> & getFieldVariable(THREAD_ID tid, unsigned int var_number);
523 :
524 : /**
525 : * Returns a field variable pointer - this includes finite volume variables.
526 : */
527 : template <typename T>
528 : MooseVariableField<T> & getActualFieldVariable(THREAD_ID tid, unsigned int var_number);
529 :
530 : /**
531 : * Return a finite volume variable
532 : */
533 : template <typename T>
534 : MooseVariableFV<T> & getFVVariable(THREAD_ID tid, const std::string & var_name);
535 :
536 : /**
537 : * Gets a reference to a scalar variable with specified number
538 : *
539 : * @param tid Thread id
540 : * @param var_name A string which is the name of the variable to get.
541 : * @return reference the variable (class)
542 : */
543 : virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid,
544 : const std::string & var_name) const;
545 :
546 : /**
547 : * Gets a reference to a variable with specified number
548 : *
549 : * @param tid Thread id
550 : * @param var_number libMesh variable number
551 : * @return reference the variable (class)
552 : */
553 : virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid, unsigned int var_number) const;
554 :
555 : /**
556 : * Get the block where a variable of this system is defined
557 : *
558 : * @param var_number The number of the variable
559 : * @return the set of subdomain ids where the variable is active (defined)
560 : */
561 : virtual const std::set<SubdomainID> * getVariableBlocks(unsigned int var_number);
562 :
563 : /**
564 : * Get the number of variables in this system
565 : * @return the number of variables
566 : */
567 : virtual unsigned int nVariables() const;
568 :
569 : /**
570 : * Get the number of field variables in this system
571 : * @return the number of field variables
572 : */
573 : unsigned int nFieldVariables() const;
574 :
575 : /**
576 : * Get the number of finite volume variables in this system
577 : * @return the number of finite volume variables
578 : */
579 : unsigned int nFVVariables() const;
580 :
581 : /**
582 : * Gets the maximum number of dofs used by any one variable on any one element
583 : *
584 : * @return The max
585 : */
586 77 : std::size_t getMaxVarNDofsPerElem() const { return _max_var_n_dofs_per_elem; }
587 :
588 : /**
589 : * Gets the maximum number of dofs used by any one variable on any one node
590 : *
591 : * @return The max
592 : */
593 : std::size_t getMaxVarNDofsPerNode() const { return _max_var_n_dofs_per_node; }
594 :
595 : /**
596 : * assign the maximum element dofs
597 : */
598 61674 : void assignMaxVarNDofsPerElem(std::size_t max_dofs) { _max_var_n_dofs_per_elem = max_dofs; }
599 :
600 : /**
601 : * assign the maximum node dofs
602 : */
603 61674 : void assignMaxVarNDofsPerNode(std::size_t max_dofs) { _max_var_n_dofs_per_node = max_dofs; }
604 :
605 : /**
606 : * Adds this variable to the list of variables to be zeroed during each residual evaluation.
607 : * @param var_name The name of the variable to be zeroed.
608 : */
609 : virtual void addVariableToZeroOnResidual(std::string var_name);
610 :
611 : /**
612 : * Adds this variable to the list of variables to be zeroed during each Jacobian evaluation.
613 : * @param var_name The name of the variable to be zeroed.
614 : */
615 : virtual void addVariableToZeroOnJacobian(std::string var_name);
616 :
617 : /**
618 : * Zero out the solution for the list of variables passed in.
619 : *
620 : * @ param vars_to_be_zeroed The variable names in this vector will have their solutions set to
621 : * zero after this call
622 : */
623 : virtual void zeroVariables(std::vector<std::string> & vars_to_be_zeroed);
624 :
625 : /**
626 : * Zero out the solution for the variables that were registered as needing to have their solutions
627 : * zeroed on out on residual evaluation by a call to addVariableToZeroOnResidual()
628 : */
629 : virtual void zeroVariablesForResidual();
630 :
631 : /**
632 : * Zero out the solution for the variables that were registered as needing to have their solutions
633 : * zeroed on out on Jacobian evaluation by a call to addVariableToZeroOnResidual()
634 : */
635 : virtual void zeroVariablesForJacobian();
636 :
637 : /**
638 : * Get minimal quadrature order needed for integrating variables in this system
639 : * @return The minimal order of quadrature
640 : */
641 : virtual libMesh::Order getMinQuadratureOrder();
642 :
643 : /**
644 : * Prepare the system for use
645 : * @param tid ID of the thread
646 : */
647 : virtual void prepare(THREAD_ID tid);
648 :
649 : /**
650 : * Prepare the system for use on sides
651 : *
652 : * This will try to reuse the preparation done on the element.
653 : *
654 : * @param tid ID of the thread
655 : * @param resize_data Pass True if this system needs to resize residual and jacobian
656 : * datastructures based on preparing this face
657 : */
658 : virtual void prepareFace(THREAD_ID tid, bool resize_data);
659 :
660 : /**
661 : * Prepare the system for use
662 : * @param tid ID of the thread
663 : */
664 : virtual void prepareNeighbor(THREAD_ID tid);
665 :
666 : /**
667 : * Prepare the system for use for lower dimensional elements
668 : * @param tid ID of the thread
669 : */
670 : virtual void prepareLowerD(THREAD_ID tid);
671 :
672 : /**
673 : * Reinit an element assembly info
674 : * @param elem Which element we are reinitializing for
675 : * @param tid ID of the thread
676 : */
677 : virtual void reinitElem(const Elem * elem, THREAD_ID tid);
678 :
679 : /**
680 : * Reinit assembly info for a side of an element
681 : * @param elem The element
682 : * @param side Side of of the element
683 : * @param tid Thread ID
684 : */
685 : virtual void reinitElemFace(const Elem * elem, unsigned int side, THREAD_ID tid);
686 :
687 : /**
688 : * Compute the values of the variables at all the current points.
689 : */
690 : virtual void reinitNeighborFace(const Elem * elem, unsigned int side, THREAD_ID tid);
691 :
692 : /**
693 : * Compute the values of the variables at all the current points.
694 : */
695 : virtual void reinitNeighbor(const Elem * elem, THREAD_ID tid);
696 :
697 : /**
698 : * Compute the values of the variables on the lower dimensional element
699 : */
700 : virtual void reinitLowerD(THREAD_ID tid);
701 :
702 : /**
703 : * Reinit nodal assembly info
704 : * @param node Node to reinit for
705 : * @param tid Thread ID
706 : */
707 : virtual void reinitNode(const Node * node, THREAD_ID tid);
708 :
709 : /**
710 : * Reinit nodal assembly info on a face
711 : * @param node Node to reinit
712 : * @param bnd_id Boundary ID
713 : * @param tid Thread ID
714 : */
715 : virtual void reinitNodeFace(const Node * node, BoundaryID bnd_id, THREAD_ID tid);
716 :
717 : /**
718 : * Reinit variables at a set of nodes
719 : * @param nodes List of node ids to reinit
720 : * @param tid Thread ID
721 : */
722 : virtual void reinitNodes(const std::vector<dof_id_type> & nodes, THREAD_ID tid);
723 :
724 : /**
725 : * Reinit variables at a set of neighbor nodes
726 : * @param nodes List of node ids to reinit
727 : * @param tid Thread ID
728 : */
729 : virtual void reinitNodesNeighbor(const std::vector<dof_id_type> & nodes, THREAD_ID tid);
730 :
731 : /**
732 : * Reinit scalar varaibles
733 : * @param tid Thread ID
734 : * @param reinit_for_derivative_reordering A flag indicating whether we are reinitializing for the
735 : * purpose of re-ordering derivative information for ADNodalBCs
736 : */
737 : virtual void reinitScalars(THREAD_ID tid, bool reinit_for_derivative_reordering = false);
738 :
739 : /**
740 : * Add info about variable that will be copied
741 : *
742 : * @param dest_name Name of the nodal variable being used for copying into (name is from the
743 : * exodusII file)
744 : * @param source_name Name of the nodal variable being used for copying from (name is from the
745 : * exodusII file)
746 : * @param timestep Timestep in the file being used
747 : */
748 : virtual void addVariableToCopy(const std::string & dest_name,
749 : const std::string & source_name,
750 : const std::string & timestep);
751 :
752 786927032 : const std::vector<MooseVariableFieldBase *> & getVariables(THREAD_ID tid)
753 : {
754 786927032 : return _vars[tid].fieldVariables();
755 : }
756 :
757 63785 : const VariableWarehouse & variableWarehouse(THREAD_ID tid = 0) const { return _vars[tid]; }
758 :
759 70311175 : const std::vector<MooseVariableScalar *> & getScalarVariables(THREAD_ID tid)
760 : {
761 70311175 : return _vars[tid].scalars();
762 : }
763 :
764 333 : const std::set<SubdomainID> & getSubdomainsForVar(unsigned int var_number) const
765 : {
766 333 : return _var_map.at(var_number);
767 : }
768 :
769 : /**
770 : * Get the block where a variable of this system is defined
771 : *
772 : * @param var_name The name of the variable
773 : * @return the set of subdomain ids where the variable is active (defined)
774 : */
775 : const std::set<SubdomainID> & getSubdomainsForVar(const std::string & var_name) const;
776 :
777 : /**
778 : * Remove a vector from the system with the given name.
779 : */
780 : void removeVector(const std::string & name);
781 :
782 : /**
783 : * Adds a solution length vector to the system.
784 : *
785 : * @param vector_name The name of the vector.
786 : * @param project Whether or not to project this vector when doing mesh refinement.
787 : * If the vector is just going to be recomputed then there is no need to project
788 : * it.
789 : * @param type What type of parallel vector. This is usually either PARALLEL or GHOSTED.
790 : * GHOSTED is needed if you are going to be accessing
791 : * off-processor entries.
792 : * The ghosting pattern is the same as the solution
793 : * vector.
794 : */
795 : NumericVector<Number> &
796 : addVector(const std::string & vector_name, const bool project, const libMesh::ParallelType type);
797 :
798 : /**
799 : * Adds a solution length vector to the system with the specified TagID
800 : *
801 : * @param tag_name The name of the tag
802 : * @param project Whether or not to project this vector when doing mesh refinement.
803 : * If the vector is just going to be recomputed then there is no need to project
804 : * it.
805 : * @param type What type of parallel vector. This is usually either PARALLEL or GHOSTED.
806 : * GHOSTED is needed if you are going to be accessing
807 : * off-processor entries.
808 : * The ghosting pattern is the same as the solution
809 : * vector.
810 : */
811 : NumericVector<Number> &
812 : addVector(TagID tag, const bool project, const libMesh::ParallelType type);
813 :
814 : /**
815 : * Close vector with the given tag
816 : */
817 : void closeTaggedVector(const TagID tag);
818 : /**
819 : * Close all vectors for given tags
820 : */
821 : void closeTaggedVectors(const std::set<TagID> & tags);
822 :
823 : /**
824 : * Zero vector with the given tag
825 : */
826 : void zeroTaggedVector(const TagID tag);
827 : /**
828 : * Zero all vectors for given tags
829 : */
830 : void zeroTaggedVectors(const std::set<TagID> & tags);
831 :
832 : /**
833 : * Remove a solution length vector from the system with the specified TagID
834 : *
835 : * @param tag_id Tag ID
836 : */
837 : void removeVector(TagID tag_id);
838 :
839 : /// set all the global dof indices for a variable
840 : /// @param var_name The name of the variable
841 : void setVariableGlobalDoFs(const std::string & var_name);
842 :
843 : /// Get the global dof indices of a variable, this needs to be called
844 : /// after the indices have been set by `setVariableGlobalDoFs`
845 90 : const std::vector<dof_id_type> & getVariableGlobalDoFs() { return _var_all_dof_indices; }
846 :
847 : /**
848 : * Adds a matrix with a given tag
849 : *
850 : * @param tag_name The name of the tag
851 : */
852 : libMesh::SparseMatrix<Number> & addMatrix(TagID tag);
853 :
854 : /**
855 : * Removes a matrix with a given tag
856 : *
857 : * @param tag_name The name of the tag
858 : */
859 : void removeMatrix(TagID tag);
860 :
861 : virtual const std::string & name() const;
862 :
863 6830662 : const std::vector<VariableName> & getVariableNames() const { return _vars[0].names(); }
864 :
865 : void getStandardFieldVariableNames(std::vector<VariableName> & std_field_variables) const;
866 :
867 : /**
868 : * Returns the maximum number of all variables on the system
869 : */
870 : unsigned int getMaxVariableNumber() const { return _max_var_number; }
871 :
872 0 : virtual void computeVariables(const NumericVector<Number> & /*soln*/) {}
873 :
874 : void copyVars(libMesh::ExodusII_IO & io);
875 :
876 : /**
877 : * Copy current solution into old and older
878 : */
879 : virtual void copySolutionsBackwards();
880 :
881 : void addTimeIntegrator(const std::string & type,
882 : const std::string & name,
883 : InputParameters & parameters);
884 :
885 : /// Whether or not there are variables to be restarted from an Exodus mesh file
886 108510 : bool hasVarCopy() const { return _var_to_copy.size() > 0; }
887 :
888 : /**
889 : * Add the scaling factor vector to the system
890 : */
891 : void addScalingVector();
892 :
893 : /**
894 : * Whether or not the solution states have been initialized via initSolutionState()
895 : *
896 : * After the solution states have been initialized, additional solution
897 : * states cannot be added.
898 : */
899 143 : bool solutionStatesInitialized() const { return _solution_states_initialized; }
900 :
901 : /// Setup Functions
902 : virtual void initialSetup();
903 : virtual void timestepSetup();
904 : virtual void customSetup(const ExecFlagType & exec_type);
905 : virtual void subdomainSetup();
906 : virtual void residualSetup();
907 : virtual void jacobianSetup();
908 :
909 : /**
910 : * Clear all dof indices from moose variables
911 : */
912 : void clearAllDofIndices();
913 :
914 : /**
915 : * Set the active vector tags for the variables
916 : */
917 : void setActiveVariableCoupleableVectorTags(const std::set<TagID> & vtags, THREAD_ID tid);
918 :
919 : /**
920 : * Set the active vector tags for the scalar variables
921 : */
922 : void setActiveScalarVariableCoupleableVectorTags(const std::set<TagID> & vtags, THREAD_ID tid);
923 :
924 : /**
925 : * @return the type of variables this system holds, e.g. nonlinear or auxiliary
926 : */
927 5079 : Moose::VarKindType varKind() const { return _var_kind; }
928 :
929 : /**
930 : * Compute time derivatives, auxiliary variables, etc.
931 : * @param type Our current execution stage
932 : */
933 : virtual void compute(ExecFlagType type) = 0;
934 :
935 : /**
936 : * Copy time integrators from another system
937 : */
938 : void copyTimeIntegrators(const SystemBase & other_sys);
939 :
940 : /**
941 : * Retrieve the time integrator that integrates the given variable's equation
942 : */
943 : const TimeIntegrator & getTimeIntegrator(const unsigned int var_num) const;
944 :
945 : /**
946 : * Retrieve the time integrator that integrates the given variable's equation. If no suitable time
947 : * integrator is found (this could happen for instance if we're solving a non-transient problem),
948 : * then a nullptr will be returned
949 : */
950 : const TimeIntegrator * queryTimeIntegrator(const unsigned int var_num) const;
951 :
952 : /**
953 : * @returns All the time integrators owned by this system
954 : */
955 : const std::vector<std::shared_ptr<TimeIntegrator>> & getTimeIntegrators();
956 :
957 : /**
958 : * @returns The prefix used for this system for solver settings for PETSc. This prefix is used to
959 : * prevent collision of solver settings for different systems. Note that this prefix does not have
960 : * a leading dash so it's appropriate for passage straight to PETSc APIs
961 : */
962 : std::string prefix() const;
963 :
964 : /**
965 : * size the matrix data for each variable for the number of matrix tags we have
966 : */
967 : void sizeVariableMatrixData();
968 :
969 : /**
970 : * Skip the next copy from the solution vector to the old solution vector
971 : * old -> older is still performed
972 : */
973 324 : void skipNextSolutionToOldCopy() { _skip_next_solution_to_old_copy = true; }
974 :
975 : protected:
976 : /**
977 : * Internal getter for solution owned by libMesh.
978 : */
979 : virtual NumericVector<Number> & solutionInternal() const = 0;
980 :
981 : /// The subproblem for whom this class holds variable data, etc; this can either be the governing
982 : /// finite element/volume problem or a subjugate displaced problem
983 : SubProblem & _subproblem;
984 :
985 : /// the governing finite element/volume problem
986 : FEProblemBase & _fe_problem;
987 :
988 : MooseApp & _app;
989 : Factory & _factory;
990 :
991 : MooseMesh & _mesh;
992 : /// The name of this system
993 : std::string _name;
994 :
995 : /// Variable warehouses (one for each thread)
996 : std::vector<VariableWarehouse> _vars;
997 : /// Map of variables (variable id -> array of subdomains where it lives)
998 : std::map<unsigned int, std::set<SubdomainID>> _var_map;
999 : /// Maximum variable number
1000 : unsigned int _max_var_number;
1001 :
1002 : std::vector<std::string> _vars_to_be_zeroed_on_residual;
1003 : std::vector<std::string> _vars_to_be_zeroed_on_jacobian;
1004 :
1005 : /// solution vector for u^dot
1006 : NumericVector<Number> * _u_dot;
1007 : /// solution vector for u^dotdot
1008 : NumericVector<Number> * _u_dotdot;
1009 :
1010 : /// old solution vector for u^dot
1011 : NumericVector<Number> * _u_dot_old;
1012 : /// old solution vector for u^dotdot
1013 : NumericVector<Number> * _u_dotdot_old;
1014 :
1015 : /// Derivative of time derivative of u with respect to uj. This depends on the time integration
1016 : /// scheme
1017 : std::vector<Real> _du_dot_du;
1018 : Real _du_dotdot_du;
1019 :
1020 : /// Tagged vectors (pointer)
1021 : std::vector<NumericVector<Number> *> _tagged_vectors;
1022 : /// Tagged matrices (pointer)
1023 : std::vector<libMesh::SparseMatrix<Number> *> _tagged_matrices;
1024 : /// Active tagged matrices. A matrix is active if its tag-matrix pair is present in the map. We use a map instead of a vector so that users can easily add and remove to this container with calls to (de)activateMatrixTag
1025 : std::unordered_map<TagID, libMesh::SparseMatrix<Number> *> _active_tagged_matrices;
1026 : /// Active flags for tagged matrices
1027 : std::vector<bool> _matrix_tag_active_flags;
1028 :
1029 : // Used for saving old solutions so that they wont be accidentally changed
1030 : NumericVector<Real> * _saved_old;
1031 : NumericVector<Real> * _saved_older;
1032 :
1033 : // Used for saving old u_dot and u_dotdot so that they wont be accidentally changed
1034 : NumericVector<Real> * _saved_dot_old;
1035 : NumericVector<Real> * _saved_dotdot_old;
1036 :
1037 : /// default kind of variables in this system
1038 : Moose::VarKindType _var_kind;
1039 :
1040 : std::vector<VarCopyInfo> _var_to_copy;
1041 :
1042 : /// Maximum number of dofs for any one variable on any one element
1043 : size_t _max_var_n_dofs_per_elem;
1044 :
1045 : /// Maximum number of dofs for any one variable on any one node
1046 : size_t _max_var_n_dofs_per_node;
1047 :
1048 : /// Time integrator
1049 : std::vector<std::shared_ptr<TimeIntegrator>> _time_integrators;
1050 :
1051 : /// Map variable number to its pointer
1052 : std::vector<std::vector<MooseVariableFieldBase *>> _numbered_vars;
1053 :
1054 : /// Whether to automatically scale the variables
1055 : bool _automatic_scaling;
1056 :
1057 : /// True if printing out additional information
1058 : bool _verbose;
1059 :
1060 : /// Whether or not the solution states have been initialized
1061 : bool _solution_states_initialized;
1062 :
1063 : /// Container for the dof indices of a given variable
1064 : std::vector<dof_id_type> _var_all_dof_indices;
1065 :
1066 : /// Serialized version of the solution vector, or nullptr if a
1067 : /// serialized solution is not needed
1068 : std::unique_ptr<NumericVector<Number>> _serialized_solution;
1069 :
1070 : private:
1071 : /**
1072 : * Gets the vector name used for an old (not current) solution state.
1073 : */
1074 : TagName oldSolutionStateVectorName(const unsigned int,
1075 : Moose::SolutionIterationType iteration_type) const;
1076 :
1077 : /// 2D array of solution state vector pointers; first index corresponds to
1078 : /// SolutionIterationType, second index corresponds to state index (0=current, 1=old, 2=older)
1079 : std::array<std::vector<NumericVector<Number> *>, 3> _solution_states;
1080 : /// The saved solution states (0 = current, 1 = old, 2 = older, etc)
1081 : std::vector<NumericVector<Number> *> _saved_solution_states;
1082 : /// Whether to skip the next copy from the solution to the old vector
1083 : bool _skip_next_solution_to_old_copy;
1084 : };
1085 :
1086 : inline bool
1087 202107997 : SystemBase::hasSolutionState(const unsigned int state,
1088 : const Moose::SolutionIterationType iteration_type) const
1089 : {
1090 202107997 : return _solution_states[static_cast<unsigned short>(iteration_type)].size() > state;
1091 : }
1092 :
1093 : #define PARALLEL_TRY
1094 :
1095 : #define PARALLEL_CATCH _fe_problem.checkExceptionAndStopSolve();
|