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 <vector>
13 :
14 : #include "DataIO.h"
15 : #include "MooseTypes.h"
16 : #include "VariableWarehouse.h"
17 : #include "InputParameters.h"
18 : #include "MooseVariableBase.h"
19 : #include "ConsoleStreamInterface.h"
20 :
21 : // libMesh
22 : #include "libmesh/exodusII_io.h"
23 : #include "libmesh/parallel_object.h"
24 : #include "libmesh/numeric_vector.h"
25 : #include "libmesh/sparse_matrix.h"
26 :
27 : // Forward declarations
28 : class Factory;
29 : class MooseApp;
30 : class MooseVariableFieldBase;
31 : template <typename>
32 : class MooseVariableFE;
33 : typedef MooseVariableFE<Real> MooseVariable;
34 : typedef MooseVariableFE<VectorValue<Real>> VectorMooseVariable;
35 : class MooseMesh;
36 : class SubProblem;
37 : class SystemBase;
38 : class TimeIntegrator;
39 : class InputParameters;
40 : class FEProblemBase;
41 :
42 : // libMesh forward declarations
43 : namespace libMesh
44 : {
45 : class System;
46 : class DofMap;
47 : class FEType;
48 : }
49 :
50 : /**
51 : * ///< Type of coordinate system
52 : */
53 : void extraSendList(std::vector<dof_id_type> & send_list, void * context);
54 :
55 : /**
56 : * Free function used for a libMesh callback
57 : */
58 : void extraSparsity(libMesh::SparsityPattern::Graph & sparsity,
59 : std::vector<dof_id_type> & n_nz,
60 : std::vector<dof_id_type> & n_oz,
61 : void * context);
62 :
63 : /**
64 : * Information about variables that will be copied
65 : */
66 : struct VarCopyInfo
67 : {
68 395 : VarCopyInfo(const std::string & dest_name,
69 : const std::string & source_name,
70 : const std::string & timestep)
71 395 : : _dest_name(dest_name), _source_name(source_name), _timestep(timestep)
72 : {
73 395 : }
74 :
75 : std::string _dest_name;
76 : std::string _source_name;
77 : std::string _timestep;
78 : };
79 :
80 : /**
81 : * Base class for a system (of equations)
82 : *
83 : */
84 : class SystemBase : public libMesh::ParallelObject, public ConsoleStreamInterface
85 :
86 : {
87 : public:
88 : SystemBase(SubProblem & subproblem,
89 : FEProblemBase & fe_problem,
90 : const std::string & name,
91 : Moose::VarKindType var_kind);
92 111728 : virtual ~SystemBase() {}
93 :
94 : /**
95 : * Gets the number of this system
96 : * @return The number of this system
97 : */
98 : unsigned int number() const;
99 39557794 : MooseMesh & mesh() { return _mesh; }
100 : const MooseMesh & mesh() const { return _mesh; }
101 158319961 : SubProblem & subproblem() { return _subproblem; }
102 1563027 : const SubProblem & subproblem() const { return _subproblem; }
103 916 : FEProblemBase & feProblem() { return _fe_problem; }
104 : const FEProblemBase & feProblem() const { return _fe_problem; }
105 :
106 : /**
107 : * Applies scaling factors to the system's variables
108 : * @param inverse_scaling_factors A vector containing the inverse of each variable's scaling
109 : * factor, e.g. 1 / scaling_factor
110 : */
111 : void applyScalingFactors(const std::vector<Real> & inverse_scaling_factors);
112 :
113 : /**
114 : * Whether we are computing an initial Jacobian for automatic variable scaling
115 : */
116 : bool computingScalingJacobian() const;
117 :
118 : /**
119 : * Getter for whether we are performing automatic scaling
120 : * @return whether we are performing automatic scaling
121 : */
122 13780 : bool automaticScaling() const { return _automatic_scaling; }
123 :
124 : /**
125 : * Setter for whether we are performing automatic scaling
126 : * @param automatic_scaling A boolean representing whether we are performing automatic scaling
127 : */
128 60742 : void automaticScaling(bool automatic_scaling) { _automatic_scaling = automatic_scaling; }
129 :
130 : /**
131 : * Sets the verbose flag
132 : * @param[in] verbose Verbose flag
133 : */
134 56754 : void setVerboseFlag(const bool & verbose) { _verbose = verbose; }
135 :
136 : /**
137 : * Gets writeable reference to the dof map
138 : */
139 : virtual libMesh::DofMap & dofMap();
140 :
141 : /**
142 : * Gets const reference to the dof map
143 : */
144 : virtual const libMesh::DofMap & dofMap() const;
145 :
146 : /**
147 : * Get the reference to the libMesh system
148 : */
149 : virtual libMesh::System & system() = 0;
150 : virtual const libMesh::System & system() const = 0;
151 :
152 : /**
153 : * This is called prior to the libMesh system has been init'd. MOOSE system wrappers can use this
154 : * method to add vectors and matrices to the libMesh system
155 : */
156 116554 : virtual void preInit() {}
157 :
158 : /*
159 : * This is called after the libMesh system has been init'd. This can be used to initialize MOOSE
160 : * system data that relies on the libMesh system data already being initialized
161 : */
162 116554 : virtual void postInit() {}
163 :
164 : /**
165 : * Reinitialize the system when the degrees of freedom in this system have changed. This is called
166 : * after the libMesh system has been reinit'd
167 : */
168 6616 : virtual void reinit() {}
169 :
170 : /**
171 : * Called only once, just before the solve begins so objects can do some precalculations
172 : */
173 0 : virtual void initializeObjects() {}
174 :
175 : /**
176 : * Update the system (doing libMesh magic)
177 : */
178 : void update();
179 :
180 : /**
181 : * Solve the system (using libMesh magic)
182 : */
183 : virtual void solve();
184 :
185 : virtual void copyOldSolutions();
186 : virtual void copyPreviousNonlinearSolutions();
187 : virtual void restoreSolutions();
188 :
189 : /**
190 : * The solution vector that is currently being operated on.
191 : * This is typically a ghosted vector that comes in from the Nonlinear solver.
192 : */
193 : virtual const NumericVector<Number> * const & currentSolution() const = 0;
194 :
195 54558553 : NumericVector<Number> & solution() { return solutionState(0); }
196 373091 : NumericVector<Number> & solutionOld() { return solutionState(1); }
197 11870 : NumericVector<Number> & solutionOlder() { return solutionState(2); }
198 89298 : const NumericVector<Number> & solution() const { return solutionState(0); }
199 97392 : const NumericVector<Number> & solutionOld() const { return solutionState(1); }
200 2108 : const NumericVector<Number> & solutionOlder() const { return solutionState(2); }
201 :
202 : virtual const NumericVector<Number> * solutionPreviousNewton() const;
203 : virtual NumericVector<Number> * solutionPreviousNewton();
204 :
205 : /**
206 : * Initializes the solution state.
207 : */
208 : virtual void initSolutionState();
209 :
210 : /**
211 : * Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
212 : *
213 : * If the state does not exist, it will be initialized in addition to any newer
214 : * states before it that have not been initialized.
215 : */
216 : virtual NumericVector<Number> &
217 : solutionState(const unsigned int state,
218 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time);
219 :
220 : /**
221 : * Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
222 : */
223 : virtual const NumericVector<Number> & solutionState(
224 : const unsigned int state,
225 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time) const;
226 :
227 : /**
228 : * Registers that the solution state \p state is needed.
229 : */
230 : virtual void needSolutionState(
231 : const unsigned int state,
232 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time);
233 :
234 : /**
235 : * Whether or not the system has the solution state (0 = current, 1 = old, 2 = older, etc).
236 : */
237 : virtual bool hasSolutionState(
238 : const unsigned int state,
239 : Moose::SolutionIterationType iteration_type = Moose::SolutionIterationType::Time) const;
240 :
241 : /**
242 : * Add u_dot, u_dotdot, u_dot_old and u_dotdot_old
243 : * vectors if requested by the time integrator
244 : */
245 : virtual void addDotVectors();
246 :
247 57042 : virtual std::vector<Number> & duDotDus() { return _du_dot_du; }
248 48405 : virtual Number & duDotDotDu() { return _du_dotdot_du; }
249 : virtual const Number & duDotDu(unsigned int var_num = 0) const;
250 520068 : virtual const Number & duDotDotDu() const { return _du_dotdot_du; }
251 :
252 327324290 : virtual NumericVector<Number> * solutionUDot() { return _u_dot; }
253 78377 : virtual NumericVector<Number> * solutionUDotDot() { return _u_dotdot; }
254 1231178 : virtual NumericVector<Number> * solutionUDotOld() { return _u_dot_old; }
255 1231178 : virtual NumericVector<Number> * solutionUDotDotOld() { return _u_dotdot_old; }
256 520068 : virtual const NumericVector<Number> * solutionUDot() const { return _u_dot; }
257 520068 : virtual const NumericVector<Number> * solutionUDotDot() const { return _u_dotdot; }
258 520068 : virtual const NumericVector<Number> * solutionUDotOld() const { return _u_dot_old; }
259 520068 : virtual const NumericVector<Number> * solutionUDotDotOld() const { return _u_dotdot_old; }
260 :
261 : virtual void saveOldSolutions();
262 : virtual void restoreOldSolutions();
263 :
264 : /**
265 : * Check if the named vector exists in the system.
266 : */
267 : bool hasVector(const std::string & tag_name) const;
268 :
269 : /**
270 : * Check if the tagged vector exists in the system.
271 : */
272 6141684879 : virtual bool hasVector(TagID tag_id) const
273 : {
274 6141684879 : return tag_id < _tagged_vectors.size() && _tagged_vectors[tag_id];
275 : }
276 :
277 : /**
278 : * Ideally, we should not need this API.
279 : * There exists a really bad API "addCachedResidualDirectly " in FEProblem and DisplacedProblem
280 : * This API should go away once addCachedResidualDirectly is removed in the future
281 : * Return Tag ID for Time
282 : */
283 0 : virtual TagID timeVectorTag() const { mooseError("Not implemented yet"); }
284 :
285 : /**
286 : * Return the Matrix Tag ID for System
287 : */
288 0 : virtual TagID systemMatrixTag() const { mooseError("Not implemented yet"); }
289 :
290 : /*
291 : * Return TagID for nontime
292 : */
293 0 : virtual TagID nonTimeVectorTag() const { mooseError("Not implemented yet"); }
294 :
295 : /*
296 : * Return TagID for nontime
297 : */
298 0 : virtual TagID residualVectorTag() const { mooseError("Not implemented yet"); }
299 :
300 : /**
301 : * Get the default vector tags associated with this system
302 : */
303 30376 : virtual std::set<TagID> defaultVectorTags() const
304 : {
305 30376 : return {timeVectorTag(), nonTimeVectorTag(), residualVectorTag()};
306 : }
307 : /**
308 : * Get the default matrix tags associted with this system
309 : */
310 3853 : virtual std::set<TagID> defaultMatrixTags() const { return {systemMatrixTag()}; }
311 :
312 : /**
313 : * Get a raw NumericVector by name
314 : */
315 : ///@{
316 : virtual NumericVector<Number> & getVector(const std::string & name);
317 : virtual const NumericVector<Number> & getVector(const std::string & name) const;
318 : ///@}
319 :
320 : /**
321 : * Get a raw NumericVector by tag
322 : */
323 : ///@{
324 : virtual NumericVector<Number> & getVector(TagID tag);
325 : virtual const NumericVector<Number> & getVector(TagID tag) const;
326 : ///@}
327 :
328 : /**
329 : * Associate a vector for a given tag
330 : */
331 : virtual void associateVectorToTag(NumericVector<Number> & vec, TagID tag);
332 :
333 : /**
334 : * Disassociate a given vector from a given tag
335 : */
336 : virtual void disassociateVectorFromTag(NumericVector<Number> & vec, TagID tag);
337 :
338 : /**
339 : * Disassociate any vector that is associated with a given tag
340 : */
341 : virtual void disassociateVectorFromTag(TagID tag);
342 :
343 : /**
344 : * Disassociate the vectors associated with the default vector tags of this system
345 : */
346 : virtual void disassociateDefaultVectorTags();
347 :
348 : /**
349 : * Check if the tagged matrix exists in the system.
350 : */
351 2280217837 : virtual bool hasMatrix(TagID tag) const
352 : {
353 2280217837 : return tag < _tagged_matrices.size() && _tagged_matrices[tag];
354 : }
355 :
356 : /**
357 : * Get a raw SparseMatrix
358 : */
359 : virtual libMesh::SparseMatrix<Number> & getMatrix(TagID tag);
360 :
361 : /**
362 : * Get a raw SparseMatrix
363 : */
364 : virtual const libMesh::SparseMatrix<Number> & getMatrix(TagID tag) const;
365 :
366 : /**
367 : * Make all exsiting matrices ative
368 : */
369 : virtual void activeAllMatrixTags();
370 :
371 : /**
372 : * Active a matrix for tag
373 : */
374 : virtual void activeMatrixTag(TagID tag);
375 :
376 : /**
377 : * If or not a matrix tag is active
378 : */
379 : virtual bool matrixTagActive(TagID tag) const;
380 :
381 : /**
382 : * deactive a matrix for tag
383 : */
384 : virtual void deactiveMatrixTag(TagID tag);
385 :
386 : /**
387 : * Make matrices inactive
388 : */
389 : virtual void deactiveAllMatrixTags();
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 57788 : 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 57788 : 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 839478603 : const std::vector<MooseVariableFieldBase *> & getVariables(THREAD_ID tid)
753 : {
754 839478603 : return _vars[tid].fieldVariables();
755 : }
756 :
757 74822821 : const std::vector<MooseVariableScalar *> & getScalarVariables(THREAD_ID tid)
758 : {
759 74822821 : return _vars[tid].scalars();
760 : }
761 :
762 336 : const std::set<SubdomainID> & getSubdomainsForVar(unsigned int var_number) const
763 : {
764 336 : return _var_map.at(var_number);
765 : }
766 :
767 : /**
768 : * Get the block where a variable of this system is defined
769 : *
770 : * @param var_name The name of the variable
771 : * @return the set of subdomain ids where the variable is active (defined)
772 : */
773 : const std::set<SubdomainID> & getSubdomainsForVar(const std::string & var_name) const;
774 :
775 : /**
776 : * Remove a vector from the system with the given name.
777 : */
778 : void removeVector(const std::string & name);
779 :
780 : /**
781 : * Adds a solution length vector to the system.
782 : *
783 : * @param vector_name The name of the vector.
784 : * @param project Whether or not to project this vector when doing mesh refinement.
785 : * If the vector is just going to be recomputed then there is no need to project
786 : * it.
787 : * @param type What type of parallel vector. This is usually either PARALLEL or GHOSTED.
788 : * GHOSTED is needed if you are going to be accessing
789 : * off-processor entries.
790 : * The ghosting pattern is the same as the solution
791 : * vector.
792 : */
793 : NumericVector<Number> &
794 : addVector(const std::string & vector_name, const bool project, const libMesh::ParallelType type);
795 :
796 : /**
797 : * Adds a solution length vector to the system with the specified TagID
798 : *
799 : * @param tag_name The name of the tag
800 : * @param project Whether or not to project this vector when doing mesh refinement.
801 : * If the vector is just going to be recomputed then there is no need to project
802 : * it.
803 : * @param type What type of parallel vector. This is usually either PARALLEL or GHOSTED.
804 : * GHOSTED is needed if you are going to be accessing
805 : * off-processor entries.
806 : * The ghosting pattern is the same as the solution
807 : * vector.
808 : */
809 : NumericVector<Number> &
810 : addVector(TagID tag, const bool project, const libMesh::ParallelType type);
811 :
812 : /**
813 : * Close vector with the given tag
814 : */
815 : void closeTaggedVector(const TagID tag);
816 : /**
817 : * Close all vectors for given tags
818 : */
819 : void closeTaggedVectors(const std::set<TagID> & tags);
820 :
821 : /**
822 : * Zero vector with the given tag
823 : */
824 : void zeroTaggedVector(const TagID tag);
825 : /**
826 : * Zero all vectors for given tags
827 : */
828 : void zeroTaggedVectors(const std::set<TagID> & tags);
829 :
830 : /**
831 : * Remove a solution length vector from the system with the specified TagID
832 : *
833 : * @param tag_id Tag ID
834 : */
835 : void removeVector(TagID tag_id);
836 :
837 : /// set all the global dof indices for a variable
838 : /// @param var_name The name of the variable
839 : void setVariableGlobalDoFs(const std::string & var_name);
840 :
841 : /// Get the global dof indices of a variable, this needs to be called
842 : /// after the indices have been set by `setVariableGlobalDoFs`
843 112 : const std::vector<dof_id_type> & getVariableGlobalDoFs() { return _var_all_dof_indices; }
844 :
845 : /**
846 : * Adds a matrix with a given tag
847 : *
848 : * @param tag_name The name of the tag
849 : */
850 : libMesh::SparseMatrix<Number> & addMatrix(TagID tag);
851 :
852 : /**
853 : * Removes a matrix with a given tag
854 : *
855 : * @param tag_name The name of the tag
856 : */
857 : void removeMatrix(TagID tag);
858 :
859 : virtual const std::string & name() const;
860 :
861 6622478 : const std::vector<VariableName> & getVariableNames() const { return _vars[0].names(); }
862 :
863 : void getStandardFieldVariableNames(std::vector<VariableName> & std_field_variables) const;
864 :
865 : /**
866 : * Returns the maximum number of all variables on the system
867 : */
868 : unsigned int getMaxVariableNumber() const { return _max_var_number; }
869 :
870 0 : virtual void computeVariables(const NumericVector<Number> & /*soln*/) {}
871 :
872 : void copyVars(libMesh::ExodusII_IO & io);
873 :
874 : /**
875 : * Copy current solution into old and older
876 : */
877 : virtual void copySolutionsBackwards();
878 :
879 : void addTimeIntegrator(const std::string & type,
880 : const std::string & name,
881 : InputParameters & parameters);
882 :
883 : /// Whether or not there are variables to be restarted from an Exodus mesh file
884 101892 : bool hasVarCopy() const { return _var_to_copy.size() > 0; }
885 :
886 : /**
887 : * Add the scaling factor vector to the system
888 : */
889 : void addScalingVector();
890 :
891 : /**
892 : * Whether or not the solution states have been initialized via initSolutionState()
893 : *
894 : * After the solution states have been initialized, additional solution
895 : * states cannot be added.
896 : */
897 143 : bool solutionStatesInitialized() const { return _solution_states_initialized; }
898 :
899 : /// Setup Functions
900 : virtual void initialSetup();
901 : virtual void timestepSetup();
902 : virtual void customSetup(const ExecFlagType & exec_type);
903 : virtual void subdomainSetup();
904 : virtual void residualSetup();
905 : virtual void jacobianSetup();
906 :
907 : /**
908 : * Clear all dof indices from moose variables
909 : */
910 : void clearAllDofIndices();
911 :
912 : /**
913 : * Set the active vector tags for the variables
914 : */
915 : void setActiveVariableCoupleableVectorTags(const std::set<TagID> & vtags, THREAD_ID tid);
916 :
917 : /**
918 : * Set the active vector tags for the scalar variables
919 : */
920 : void setActiveScalarVariableCoupleableVectorTags(const std::set<TagID> & vtags, THREAD_ID tid);
921 :
922 : /**
923 : * @return the type of variables this system holds, e.g. nonlinear or auxiliary
924 : */
925 4839 : Moose::VarKindType varKind() const { return _var_kind; }
926 :
927 : /**
928 : * Reference to the container vector which hold gradients at dofs (if it can be interpreted).
929 : * Mainly used for finite volume systems.
930 : */
931 1311 : const std::vector<std::unique_ptr<NumericVector<Number>>> & gradientContainer() const
932 : {
933 1311 : return _raw_grad_container;
934 : }
935 :
936 : /**
937 : * Compute time derivatives, auxiliary variables, etc.
938 : * @param type Our current execution stage
939 : */
940 : virtual void compute(ExecFlagType type) = 0;
941 :
942 : /**
943 : * Copy time integrators from another system
944 : */
945 : void copyTimeIntegrators(const SystemBase & other_sys);
946 :
947 : /**
948 : * Retrieve the time integrator that integrates the given variable's equation
949 : */
950 : const TimeIntegrator & getTimeIntegrator(const unsigned int var_num) const;
951 :
952 : /**
953 : * Retrieve the time integrator that integrates the given variable's equation. If no suitable time
954 : * integrator is found (this could happen for instance if we're solving a non-transient problem),
955 : * then a nullptr will be returned
956 : */
957 : const TimeIntegrator * queryTimeIntegrator(const unsigned int var_num) const;
958 :
959 : /**
960 : * @returns All the time integrators owned by this system
961 : */
962 : const std::vector<std::shared_ptr<TimeIntegrator>> & getTimeIntegrators();
963 :
964 : /**
965 : * @returns A prefix for solvers
966 : */
967 : std::string prefix() const;
968 :
969 : protected:
970 : /**
971 : * Internal getter for solution owned by libMesh.
972 : */
973 : virtual NumericVector<Number> & solutionInternal() const = 0;
974 :
975 : /// The subproblem for whom this class holds variable data, etc; this can either be the governing
976 : /// finite element/volume problem or a subjugate displaced problem
977 : SubProblem & _subproblem;
978 :
979 : /// the governing finite element/volume problem
980 : FEProblemBase & _fe_problem;
981 :
982 : MooseApp & _app;
983 : Factory & _factory;
984 :
985 : MooseMesh & _mesh;
986 : /// The name of this system
987 : std::string _name;
988 :
989 : /// Variable warehouses (one for each thread)
990 : std::vector<VariableWarehouse> _vars;
991 : /// Map of variables (variable id -> array of subdomains where it lives)
992 : std::map<unsigned int, std::set<SubdomainID>> _var_map;
993 : /// Maximum variable number
994 : unsigned int _max_var_number;
995 :
996 : std::vector<std::string> _vars_to_be_zeroed_on_residual;
997 : std::vector<std::string> _vars_to_be_zeroed_on_jacobian;
998 :
999 : /// solution vector for u^dot
1000 : NumericVector<Number> * _u_dot;
1001 : /// solution vector for u^dotdot
1002 : NumericVector<Number> * _u_dotdot;
1003 :
1004 : /// old solution vector for u^dot
1005 : NumericVector<Number> * _u_dot_old;
1006 : /// old solution vector for u^dotdot
1007 : NumericVector<Number> * _u_dotdot_old;
1008 :
1009 : /// Derivative of time derivative of u with respect to uj. This depends on the time integration
1010 : /// scheme
1011 : std::vector<Real> _du_dot_du;
1012 : Real _du_dotdot_du;
1013 :
1014 : /// Tagged vectors (pointer)
1015 : std::vector<NumericVector<Number> *> _tagged_vectors;
1016 : /// Tagged matrices (pointer)
1017 : std::vector<libMesh::SparseMatrix<Number> *> _tagged_matrices;
1018 : /// Active flags for tagged matrices
1019 : std::vector<bool> _matrix_tag_active_flags;
1020 :
1021 : // Used for saving old solutions so that they wont be accidentally changed
1022 : NumericVector<Real> * _saved_old;
1023 : NumericVector<Real> * _saved_older;
1024 :
1025 : // Used for saving old u_dot and u_dotdot so that they wont be accidentally changed
1026 : NumericVector<Real> * _saved_dot_old;
1027 : NumericVector<Real> * _saved_dotdot_old;
1028 :
1029 : /// default kind of variables in this system
1030 : Moose::VarKindType _var_kind;
1031 :
1032 : std::vector<VarCopyInfo> _var_to_copy;
1033 :
1034 : /// Maximum number of dofs for any one variable on any one element
1035 : size_t _max_var_n_dofs_per_elem;
1036 :
1037 : /// Maximum number of dofs for any one variable on any one node
1038 : size_t _max_var_n_dofs_per_node;
1039 :
1040 : /// Time integrator
1041 : std::vector<std::shared_ptr<TimeIntegrator>> _time_integrators;
1042 :
1043 : /// Map variable number to its pointer
1044 : std::vector<std::vector<MooseVariableFieldBase *>> _numbered_vars;
1045 :
1046 : /// Whether to automatically scale the variables
1047 : bool _automatic_scaling;
1048 :
1049 : /// True if printing out additional information
1050 : bool _verbose;
1051 :
1052 : /// Whether or not the solution states have been initialized
1053 : bool _solution_states_initialized;
1054 :
1055 : /// Container for the dof indices of a given variable
1056 : std::vector<dof_id_type> _var_all_dof_indices;
1057 :
1058 : /// Serialized version of the solution vector, or nullptr if a
1059 : /// serialized solution is not needed
1060 : std::unique_ptr<NumericVector<Number>> _serialized_solution;
1061 :
1062 : /// A cache for storing gradients at dof locations. We store it on the system
1063 : /// because we create copies of variables on each thread and that would
1064 : /// lead to increased data duplication when using threading-based parallelism.
1065 : std::vector<std::unique_ptr<NumericVector<Number>>> _raw_grad_container;
1066 :
1067 : private:
1068 : /**
1069 : * Gets the vector name used for an old (not current) solution state.
1070 : */
1071 : TagName oldSolutionStateVectorName(const unsigned int,
1072 : Moose::SolutionIterationType iteration_type) const;
1073 :
1074 : /// The solution states (0 = current, 1 = old, 2 = older, etc)
1075 : std::array<std::vector<NumericVector<Number> *>, 2> _solution_states;
1076 : /// The saved solution states (0 = current, 1 = old, 2 = older, etc)
1077 : std::vector<NumericVector<Number> *> _saved_solution_states;
1078 : };
1079 :
1080 : inline bool
1081 201998395 : SystemBase::hasSolutionState(const unsigned int state,
1082 : const Moose::SolutionIterationType iteration_type) const
1083 : {
1084 201998395 : return _solution_states[static_cast<unsigned short>(iteration_type)].size() > state;
1085 : }
1086 :
1087 : #define PARALLEL_TRY
1088 :
1089 : #define PARALLEL_CATCH _fe_problem.checkExceptionAndStopSolve();
|