25 #include "libmesh/id_types.h" 26 #include "libmesh/nonlinear_solver.h" 27 #include "libmesh/sparse_matrix.h" 29 #include "libmesh/vector_value.h" 36 DirectCentralDifference,
46 "Implementation of explicit time integration without invoking any of the nonlinear solver.");
48 params.
addParam<
bool>(
"use_constant_mass",
50 "If set to true, will only compute the mass matrix in the first time step, " 51 "and keep using it throughout the simulation.");
52 params.
addParam<TagName>(
"mass_matrix_tag",
"mass",
"The tag for the mass matrix");
54 params.
addParam<std::vector<VariableName>>(
57 "A subset of variables that require second-order integration (velocity and acceleration) to " 58 "be applied by this time integrator.");
60 params.
addParam<std::vector<VariableName>>(
63 "A subset of variables that require first-order integration (velocity only) to be applied by " 64 "this time integrator.");
69 MooseEnum solve_type(
"consistent lumped lump_preconditioned",
"lumped");
77 _constant_mass(getParam<bool>(
"use_constant_mass")),
79 _solution_older(_sys.solutionState(2)),
80 _vars_first(declareRestartableData<
std::unordered_set<unsigned
int>>(
"first_order_vars")),
81 _local_first_order_indices(
82 declareRestartableData<
std::vector<
dof_id_type>>(
"first_local_indices")),
83 _vars_second(declareRestartableData<
std::unordered_set<unsigned
int>>(
"second_order_vars")),
84 _local_second_order_indices(
85 declareRestartableData<
std::vector<
dof_id_type>>(
"second_local_indices"))
188 const std::unique_ptr<NumericVector<Number>> mass_first(
190 const std::unique_ptr<NumericVector<Real>> exp_res_first(
199 vel_first->pointwise_mult(*mass_first, *exp_res_first);
206 const std::unique_ptr<NumericVector<Real>> mass_second(
208 const std::unique_ptr<NumericVector<Real>> exp_res_second(
219 accel_second->pointwise_mult(*mass_second, *exp_res_second);
222 auto accel_scaled = accel_second->clone();
226 *vel_second += *accel_scaled;
259 const auto & var_names_first = getParam<std::vector<VariableName>>(
"first_order_vars");
260 const auto & var_names_second = getParam<std::vector<VariableName>>(
"second_order_vars");
261 std::vector<unsigned int> var_num_vec;
265 std::unordered_set<unsigned int> var_nums(var_num_vec.begin(), var_num_vec.end());
267 for (
const auto & var_name : var_names_first)
268 if (lm_sys.has_variable(var_name))
270 const auto var_num = lm_sys.variable_number(var_name);
272 var_nums.erase(var_num);
275 for (
const auto & var_name : var_names_second)
276 if (lm_sys.has_variable(var_name))
278 const auto var_num = lm_sys.variable_number(var_name);
280 var_nums.erase(var_num);
284 if (!var_nums.empty())
285 mooseError(
"Not all nonlinear variables have their order specified.");
287 std::vector<dof_id_type> var_dof_indices, work_vec;
292 lm_sys.get_dof_map().local_variable_indices(var_dof_indices, lm_sys.get_mesh(), var_num);
293 std::merge(work_vec.begin(),
295 var_dof_indices.begin(),
296 var_dof_indices.end(),
301 var_dof_indices.clear();
307 lm_sys.get_dof_map().local_variable_indices(var_dof_indices, lm_sys.get_mesh(), var_num);
308 std::merge(work_vec.begin(),
310 var_dof_indices.begin(),
311 var_dof_indices.end(),
333 mooseError(
"Time order sets are both empty.");
340 " does not exist in time order sets.");
virtual void computeJacobianTag(const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, TagID tag)
virtual TagID massMatrixTagID() const override
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
void overwriteNodeFace(NumericVector< Number > &soln)
virtual Real & time() const
NumericVector< Real > * _solution_update
_mass_matrix(getParam< TagName >("mass_matrix"))
virtual void setUDotDotRequested(const bool u_dotdot_requested)
NumericVector< Real > * _ones
std::unordered_set< unsigned int > & _vars_second
FEProblemBase & _fe_problem
NonlinearSystemBase * _nl
const bool & _constant_mass
Whether we are reusing the mass matrix.
virtual libMesh::System & system()=0
const TagName & _mass_matrix
Mass matrix name.
void setSolution(const NumericVector< Number > &soln)
void get_all_variable_numbers(std::vector< unsigned int > &all_variable_numbers) const
TimeOrder findVariableTimeOrder(unsigned int var_num) const
Retrieve the order of the highest time derivative of a variable.
virtual void postResidual(NumericVector< Number > &residual) override
Implements a form of the central difference time integrator that calculates acceleration directly fro...
const Parallel::Communicator & _communicator
NumericVector< Number > * _Re_time
virtual void setUDotOldRequested(const bool u_dot_old_requested)
bool converged(const std::vector< std::pair< unsigned int, Real >> &residuals, const std::vector< Real > &abs_tolerances)
Based on the residuals, determine if the iterative process converged or not.
libMesh::NonlinearImplicitSystem * _nonlinear_implicit_system
static InputParameters validParams()
std::unordered_set< unsigned int > & _vars_first
std::vector< dof_id_type > & _local_second_order_indices
virtual TagID getMatrixTagID(const TagName &tag_name) const
registerMooseObject("SolidMechanicsApp", ExplicitMixedOrder)
virtual void setUDotRequested(const bool u_dot_requested)
NumericVector< Real > * _explicit_residual
virtual NumericVector< Number > * solutionUDot()
SubProblem & subproblem()
std::unique_ptr< NumericVector< Number > > solution
static InputParameters validParams()
unsigned int _n_linear_iterations
virtual void computeTimeDerivatives() override
const std::string & variable_name(const unsigned int i) const
unsigned int number() const
void computeResidual(libMesh::NonlinearImplicitSystem &sys, const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual)
registerMooseObjectRenamed("SolidMechanicsApp", DirectCentralDifference, "10/14/2025 00:00", ExplicitMixedOrder)
const NumericVector< Number > *const & _solution
NumericVector< Real > * _mass_matrix_diag_inverted
virtual void init() override
virtual bool performExplicitSolve(SparseMatrix< Number > &mass_matrix) override
virtual void init() override
static std::unique_ptr< NumericVector< Number > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
void mooseError(Args &&... args) const
std::unique_ptr< NumericVector< Number > > current_local_solution
virtual Real & timeOld() const
const NumericVector< Number > & _solution_old
unsigned int _n_nonlinear_iterations
virtual void solve() override
ExplicitMixedOrder(const InputParameters ¶meters)
virtual NumericVector< Number > * solutionUDotDot()
NumericVector< Number > * _Re_non_time
NumericVector< Number > & solutionOld()
const SparseMatrix< Number > & get_system_matrix() const
std::vector< dof_id_type > & _local_first_order_indices
void ErrorVector unsigned int