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 : #include "TimeIntegrator.h"
11 : #include "FEProblem.h"
12 : #include "NonlinearSystemBase.h"
13 :
14 : #include "libmesh/nonlinear_implicit_system.h"
15 : #include "libmesh/nonlinear_solver.h"
16 : #include "libmesh/dof_map.h"
17 :
18 : using namespace libMesh;
19 :
20 : InputParameters
21 142346 : TimeIntegrator::validParams()
22 : {
23 142346 : InputParameters params = MooseObject::validParams();
24 569384 : params.addParam<std::vector<VariableName>>(
25 : "variables", {}, "A subset of the variables that this time integrator should be applied to");
26 142346 : params.registerBase("TimeIntegrator");
27 142346 : return params;
28 0 : }
29 :
30 60187 : TimeIntegrator::TimeIntegrator(const InputParameters & parameters)
31 : : MooseObject(parameters),
32 : Restartable(this, "TimeIntegrators"),
33 240748 : NonlinearTimeIntegratorInterface(*getCheckedPointerParam<FEProblemBase *>("_fe_problem_base"),
34 240748 : *getCheckedPointerParam<SystemBase *>("_sys")),
35 240748 : LinearTimeIntegratorInterface(*getCheckedPointerParam<SystemBase *>("_sys")),
36 180561 : _fe_problem(*getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
37 240748 : _sys(*getCheckedPointerParam<SystemBase *>("_sys")),
38 60187 : _du_dot_du(_sys.duDotDus()),
39 60187 : _solution(_sys.currentSolution()),
40 60187 : _solution_old(_sys.solutionState(1)),
41 60187 : _solution_sub(declareRestartableDataWithContext<std::unique_ptr<NumericVector<Number>>>(
42 60187 : "solution_sub", &const_cast<libMesh::Parallel::Communicator &>(this->comm()))),
43 60187 : _solution_old_sub(declareRestartableDataWithContext<std::unique_ptr<NumericVector<Number>>>(
44 60187 : "solution_old_sub", &const_cast<libMesh::Parallel::Communicator &>(this->comm()))),
45 60187 : _t_step(_fe_problem.timeStep()),
46 60187 : _dt(_fe_problem.dt()),
47 60187 : _dt_old(_fe_problem.dtOld()),
48 60187 : _n_nonlinear_iterations(0),
49 60187 : _n_linear_iterations(0),
50 60187 : _is_lumped(false),
51 60187 : _var_restriction(declareRestartableData<bool>(
52 180561 : "var_restriction", !getParam<std::vector<VariableName>>("variables").empty())),
53 120374 : _local_indices(declareRestartableData<std::vector<dof_id_type>>("local_indices")),
54 120374 : _vars(declareRestartableData<std::unordered_set<unsigned int>>("vars")),
55 60187 : _from_subvector(
56 421309 : NumericVector<Number>::build(this->comm(), libMesh::default_solver_package(), PARALLEL))
57 : {
58 60187 : _fe_problem.setUDotRequested(true);
59 60187 : }
60 :
61 : void
62 26776 : TimeIntegrator::init()
63 : {
64 26776 : if (!_var_restriction)
65 26706 : return;
66 :
67 140 : const auto & var_names = getParam<std::vector<VariableName>>("variables");
68 70 : std::vector<unsigned int> var_num_vec;
69 70 : auto & lm_sys = _sys.system();
70 70 : lm_sys.get_all_variable_numbers(var_num_vec);
71 70 : std::unordered_set<unsigned int> var_nums(var_num_vec.begin(), var_num_vec.end());
72 140 : for (const auto & var_name : var_names)
73 70 : if (lm_sys.has_variable(var_name))
74 : {
75 70 : const auto var_num = lm_sys.variable_number(var_name);
76 70 : _vars.insert(var_num);
77 70 : var_nums.erase(var_num);
78 : }
79 :
80 : // If var_nums is empty then that means the user has specified all the variables in this system
81 70 : if (var_nums.empty())
82 : {
83 0 : _var_restriction = false;
84 0 : return;
85 : }
86 :
87 70 : std::vector<dof_id_type> var_dof_indices, work_vec;
88 140 : for (const auto var_num : _vars)
89 : {
90 70 : work_vec = _local_indices;
91 70 : _local_indices.clear();
92 70 : lm_sys.get_dof_map().local_variable_indices(var_dof_indices, lm_sys.get_mesh(), var_num);
93 70 : std::merge(work_vec.begin(),
94 : work_vec.end(),
95 : var_dof_indices.begin(),
96 : var_dof_indices.end(),
97 : std::back_inserter(_local_indices));
98 : }
99 :
100 70 : _solution_sub =
101 70 : NumericVector<Number>::build(_solution->comm(), libMesh::default_solver_package(), PARALLEL);
102 210 : _solution_old_sub = NumericVector<Number>::build(
103 140 : _solution_old.comm(), libMesh::default_solver_package(), PARALLEL);
104 70 : }
105 :
106 : void
107 0 : TimeIntegrator::solve()
108 : {
109 0 : mooseError("Calling TimeIntegrator::solve() is no longer supported");
110 : }
111 :
112 : void
113 246842 : TimeIntegrator::setNumIterationsLastSolve()
114 : {
115 246842 : _n_nonlinear_iterations = getNumNonlinearIterationsLastSolve();
116 246842 : _n_linear_iterations = getNumLinearIterationsLastSolve();
117 246842 : }
118 :
119 : unsigned int
120 265070 : TimeIntegrator::getNumNonlinearIterationsLastSolve() const
121 : {
122 265070 : return _nonlinear_implicit_system->n_nonlinear_iterations();
123 : }
124 :
125 : unsigned int
126 265070 : TimeIntegrator::getNumLinearIterationsLastSolve() const
127 : {
128 265070 : auto & nonlinear_solver = _nonlinear_implicit_system->nonlinear_solver;
129 : libmesh_assert(nonlinear_solver);
130 :
131 265070 : return nonlinear_solver->get_total_linear_iterations();
132 : }
133 :
134 : void
135 6772 : TimeIntegrator::copyVector(const NumericVector<Number> & from, NumericVector<Number> & to)
136 : {
137 6772 : if (!_var_restriction)
138 6398 : to = from;
139 : else
140 : {
141 374 : auto to_sub = to.get_subvector(_local_indices);
142 374 : from.create_subvector(*_from_subvector, _local_indices, false);
143 374 : *to_sub = *_from_subvector;
144 374 : to.restore_subvector(std::move(to_sub), _local_indices);
145 374 : }
146 6772 : }
147 :
148 : bool
149 9454085 : TimeIntegrator::integratesVar(const unsigned int var_num) const
150 : {
151 9454085 : if (!_var_restriction)
152 9396623 : return true;
153 :
154 57462 : return _vars.count(var_num);
155 : }
156 :
157 : void
158 4453309 : TimeIntegrator::computeDuDotDu()
159 : {
160 4453309 : const auto coeff = duDotDuCoeff();
161 13388776 : for (const auto i : index_range(_du_dot_du))
162 8935467 : if (integratesVar(i))
163 8921236 : _du_dot_du[i] = coeff / _dt;
164 4453309 : }
|